Add host boot settings to power operations page

Added BootSettingsStore and component to handle changing boot
source, boot override option and TPM required option.

Signed-off-by: Yoshie Muranaka <yoshiemuranaka@gmail.com>
Change-Id: I885dd6008aceb34b319953a2e9b6416d848baf16
diff --git a/src/views/Control/ServerPowerOperations/BootSettings.vue b/src/views/Control/ServerPowerOperations/BootSettings.vue
new file mode 100644
index 0000000..c912749
--- /dev/null
+++ b/src/views/Control/ServerPowerOperations/BootSettings.vue
@@ -0,0 +1,148 @@
+<template>
+  <div class="boot-settings 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"
+          switch
+          aria-describedby="tpm-required-policy-help-block"
+          @change="$v.form.tpmPolicyOn.$touch()"
+        >
+          {{
+            form.tpmPolicyOn ? $t('global.status.on') : $t('global.status.off')
+          }}
+        </b-form-checkbox>
+      </b-form-group>
+      <b-button
+        variant="primary"
+        type="submit"
+        class="mb-3"
+        :disabled="!$v.form.$anyDirty"
+      >
+        {{ $t('global.action.save') }}
+      </b-button>
+    </b-form>
+  </div>
+</template>
+
+<script>
+import { mapState } from 'vuex';
+import BVToastMixin from '../../../components/Mixins/BVToastMixin';
+
+export default {
+  name: 'BootSettings',
+  mixins: [BVToastMixin],
+  data() {
+    return {
+      form: {
+        bootOption: this.$store.getters['hostBootSettings/bootSource'],
+        oneTimeBoot: this.$store.getters['hostBootSettings/overrideEnabled'],
+        tpmPolicyOn: this.$store.getters['hostBootSettings/tpmEnabled']
+      }
+    };
+  },
+  computed: {
+    ...mapState('hostBootSettings', [
+      '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('hostBootSettings/getBootSettings');
+    this.$store.dispatch('hostBootSettings/getTpmPolicy');
+  },
+  methods: {
+    handleSubmit() {
+      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('hostBootSettings/saveSettings', settings)
+        .then(message => this.successToast(message))
+        .catch(({ message }) => this.errorToast(message))
+        .finally(() => {
+          this.$v.form.$reset();
+        });
+    },
+    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>
+
+<style lang="scss" scoped>
+.boot-settings {
+  background-color: $gray-200;
+}
+</style>
diff --git a/src/views/Control/ServerPowerOperations/ServerPowerOperations.vue b/src/views/Control/ServerPowerOperations/ServerPowerOperations.vue
index c9b02b3..e63d073 100644
--- a/src/views/Control/ServerPowerOperations/ServerPowerOperations.vue
+++ b/src/views/Control/ServerPowerOperations/ServerPowerOperations.vue
@@ -2,7 +2,7 @@
   <b-container fluid>
     <page-title />
     <b-row>
-      <b-col md="8" lg="8" xl="6">
+      <b-col md="8" xl="6">
         <page-section
           :section-title="$t('pageServerPowerOperations.currentStatus')"
         >
@@ -26,10 +26,20 @@
       </b-col>
     </b-row>
     <b-row>
-      <b-col md="8" lg="7" xl="8">
+      <b-col sm="8" md="6" xl="4">
+        <page-section
+          :section-title="$t('pageServerPowerOperations.hostOsBootSettings')"
+        >
+          <boot-settings />
+        </page-section>
+      </b-col>
+      <b-col sm="8" md="6" xl="7">
         <page-section
           :section-title="$t('pageServerPowerOperations.operations')"
         >
+          <b-alert :show="oneTimeBootEnabled" variant="warning">
+            {{ $t('pageServerPowerOperations.oneTimeBootWarning') }}
+          </b-alert>
           <template v-if="isOperationInProgress">
             {{ $t('pageServerPowerOperations.operationInProgress') }}
           </template>
@@ -101,10 +111,11 @@
 import PageTitle from '../../../components/Global/PageTitle';
 import PageSection from '../../../components/Global/PageSection';
 import BVToastMixin from '../../../components/Mixins/BVToastMixin';
+import BootSettings from './BootSettings';
 
 export default {
   name: 'ServerPowerOperations',
-  components: { PageTitle, PageSection },
+  components: { PageTitle, PageSection, BootSettings },
   mixins: [BVToastMixin],
   data() {
     return {
@@ -123,6 +134,9 @@
     },
     isOperationInProgress() {
       return this.$store.getters['controls/isOperationInProgress'];
+    },
+    oneTimeBootEnabled() {
+      return this.$store.getters['hostBootSettings/overrideEnabled'];
     }
   },
   created() {