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/store/index.js b/src/store/index.js
index 6bad517..2721699 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -6,6 +6,7 @@
 import LocalUserManagementStore from './modules/AccessControl/LocalUserMangementStore';
 import OverviewStore from './modules/Overview/OverviewStore';
 import FirmwareStore from './modules/Configuration/FirmwareStore';
+import BootSettingsStore from './modules/Control/BootSettingsStore';
 import ControlStore from './modules/Control/ControlStore';
 import PowerControlStore from './modules/Control/PowerControlStore';
 import NetworkSettingStore from './modules/Configuration/NetworkSettingsStore';
@@ -25,6 +26,7 @@
     localUsers: LocalUserManagementStore,
     overview: OverviewStore,
     firmware: FirmwareStore,
+    hostBootSettings: BootSettingsStore,
     controls: ControlStore,
     powerControl: PowerControlStore,
     networkSettings: NetworkSettingStore,
diff --git a/src/store/modules/Control/BootSettingsStore.js b/src/store/modules/Control/BootSettingsStore.js
new file mode 100644
index 0000000..8da586a
--- /dev/null
+++ b/src/store/modules/Control/BootSettingsStore.js
@@ -0,0 +1,136 @@
+import api from '../../api';
+import i18n from '../../../i18n';
+
+const BootSettingsStore = {
+  namespaced: true,
+  state: {
+    bootSourceOptions: [],
+    bootSource: null,
+    overrideEnabled: null,
+    tpmEnabled: null
+  },
+  getters: {
+    bootSourceOptions: state => state.bootSourceOptions,
+    bootSource: state => state.bootSource,
+    overrideEnabled: state => state.overrideEnabled,
+    tpmEnabled: state => state.tpmEnabled
+  },
+  mutations: {
+    setBootSourceOptions: (state, bootSourceOptions) =>
+      (state.bootSourceOptions = bootSourceOptions),
+    setBootSource: (state, bootSource) => (state.bootSource = bootSource),
+    setOverrideEnabled: (state, overrideEnabled) => {
+      if (overrideEnabled === 'Once') {
+        state.overrideEnabled = true;
+      } else {
+        // 'Continuous' or 'Disabled'
+        state.overrideEnabled = false;
+      }
+    },
+    setTpmPolicy: (state, tpmEnabled) => (state.tpmEnabled = tpmEnabled)
+  },
+  actions: {
+    getBootSettings({ commit }) {
+      api
+        .get('/redfish/v1/Systems/system/')
+        .then(({ data: { Boot } }) => {
+          commit(
+            'setBootSourceOptions',
+            Boot['BootSourceOverrideTarget@Redfish.AllowableValues']
+          );
+          commit('setOverrideEnabled', Boot.BootSourceOverrideEnabled);
+          commit('setBootSource', Boot.BootSourceOverrideTarget);
+        })
+        .catch(error => console.log(error));
+    },
+    saveBootSettings({ commit, dispatch }, { bootSource, overrideEnabled }) {
+      const data = { Boot: {} };
+      data.Boot.BootSourceOverrideTarget = bootSource;
+
+      if (overrideEnabled) {
+        data.Boot.BootSourceOverrideEnabled = 'Once';
+      } else if (bootSource === 'None') {
+        data.Boot.BootSourceOverrideEnabled = 'Disabled';
+      } else {
+        data.Boot.BootSourceOverrideEnabled = 'Continuous';
+      }
+
+      return api
+        .patch('/redfish/v1/Systems/system', data)
+        .then(response => {
+          // If request success, commit the values
+          commit('setBootSource', data.Boot.BootSourceOverrideTarget);
+          commit('setOverrideEnabled', data.Boot.BootSourceOverrideEnabled);
+          return response;
+        })
+        .catch(error => {
+          console.log(error);
+          // If request error, GET saved options
+          dispatch('getBootSettings');
+          return error;
+        });
+    },
+    getTpmPolicy({ commit }) {
+      // TODO: switch to Redfish when available
+      api
+        .get('/xyz/openbmc_project/control/host0/TPMEnable')
+        .then(({ data: { data: { TPMEnable } } }) =>
+          commit('setTpmPolicy', TPMEnable)
+        )
+        .catch(error => console.log(error));
+    },
+    saveTpmPolicy({ commit, dispatch }, tpmEnabled) {
+      // TODO: switch to Redfish when available
+      const data = { data: tpmEnabled };
+      return api
+        .put(
+          '/xyz/openbmc_project/control/host0/TPMEnable/attr/TPMEnable',
+          data
+        )
+        .then(response => {
+          // If request success, commit the values
+          commit('setTpmPolicy', tpmEnabled);
+          return response;
+        })
+        .catch(error => {
+          console.log(error);
+          // If request error, GET saved policy
+          dispatch('getTpmPolicy');
+          return error;
+        });
+    },
+    async saveSettings(
+      { dispatch },
+      { bootSource, overrideEnabled, tpmEnabled }
+    ) {
+      const promises = [];
+
+      if (bootSource !== null || overrideEnabled !== null) {
+        promises.push(
+          dispatch('saveBootSettings', { bootSource, overrideEnabled })
+        );
+      }
+      if (tpmEnabled !== null) {
+        promises.push(dispatch('saveTpmPolicy', tpmEnabled));
+      }
+
+      return await api.all(promises).then(
+        api.spread((...responses) => {
+          let message = i18n.t(
+            'pageServerPowerOperations.toast.successSaveSettings'
+          );
+          responses.forEach(response => {
+            if (response instanceof Error) {
+              throw new Error(
+                i18n.t('pageServerPowerOperations.toast.errorSaveSettings')
+              );
+            }
+          });
+          return message;
+        })
+      );
+    }
+  }
+};
+
+export default BootSettingsStore;