1import api from '@/store/api';
2import i18n from '@/i18n';
3
4const FirmwareStore = {
5  namespaced: true,
6  state: {
7    bmcFirmware: [],
8    hostFirmware: [],
9    bmcActiveFirmwareId: null,
10    hostActiveFirmwareId: null,
11    applyTime: null,
12    httpPushUri: null,
13    tftpAvailable: false,
14  },
15  getters: {
16    isTftpUploadAvailable: (state) => state.tftpAvailable,
17    isSingleFileUploadEnabled: (state) => state.hostFirmware.length === 0,
18    activeBmcFirmware: (state) => {
19      return state.bmcFirmware.find(
20        (firmware) => firmware.id === state.bmcActiveFirmwareId,
21      );
22    },
23    activeHostFirmware: (state) => {
24      return state.hostFirmware.find(
25        (firmware) => firmware.id === state.hostActiveFirmwareId,
26      );
27    },
28    backupBmcFirmware: (state) => {
29      return state.bmcFirmware.find(
30        (firmware) => firmware.id !== state.bmcActiveFirmwareId,
31      );
32    },
33    backupHostFirmware: (state) => {
34      return state.hostFirmware.find(
35        (firmware) => firmware.id !== state.hostActiveFirmwareId,
36      );
37    },
38  },
39  mutations: {
40    setActiveBmcFirmwareId: (state, id) => (state.bmcActiveFirmwareId = id),
41    setActiveHostFirmwareId: (state, id) => (state.hostActiveFirmwareId = id),
42    setBmcFirmware: (state, firmware) => (state.bmcFirmware = firmware),
43    setHostFirmware: (state, firmware) => (state.hostFirmware = firmware),
44    setApplyTime: (state, applyTime) => (state.applyTime = applyTime),
45    setHttpPushUri: (state, httpPushUri) => (state.httpPushUri = httpPushUri),
46    setTftpUploadAvailable: (state, tftpAvailable) =>
47      (state.tftpAvailable = tftpAvailable),
48  },
49  actions: {
50    async getFirmwareInformation({ dispatch }) {
51      dispatch('getActiveHostFirmware');
52      dispatch('getActiveBmcFirmware');
53      return await dispatch('getFirmwareInventory');
54    },
55    async getActiveBmcFirmware({ commit }) {
56      return api
57        .get(`${await this.dispatch('global/getBmcPath')}`)
58        .then(({ data: { Links } }) => {
59          const id = Links?.ActiveSoftwareImage['@odata.id'].split('/').pop();
60          commit('setActiveBmcFirmwareId', id);
61        })
62        .catch((error) => console.log(error));
63    },
64    async getActiveHostFirmware({ commit }) {
65      return api
66        .get(`${await this.dispatch('global/getSystemPath')}/Bios`)
67        .then(({ data: { Links } }) => {
68          const id = Links?.ActiveSoftwareImage['@odata.id'].split('/').pop();
69          commit('setActiveHostFirmwareId', id);
70        })
71        .catch((error) => console.log(error));
72    },
73    async getFirmwareInventory({ commit }) {
74      const inventoryList = await api
75        .get('/redfish/v1/UpdateService/FirmwareInventory')
76        .then(({ data: { Members = [] } = {} }) =>
77          Members.map((item) => api.get(item['@odata.id'])),
78        )
79        .catch((error) => console.log(error));
80      await api
81        .all(inventoryList)
82        .then((response) => {
83          const bmcFirmware = [];
84          const hostFirmware = [];
85          response.forEach(({ data }) => {
86            const firmwareType = data?.RelatedItem?.[0]?.['@odata.id']
87              .split('/')
88              .pop();
89            const item = {
90              version: data?.Version,
91              id: data?.Id,
92              location: data?.['@odata.id'],
93              status: data?.Status?.Health,
94            };
95            if (firmwareType === 'bmc') {
96              bmcFirmware.push(item);
97            } else if (firmwareType === 'Bios') {
98              hostFirmware.push(item);
99            }
100          });
101          commit('setBmcFirmware', bmcFirmware);
102          commit('setHostFirmware', hostFirmware);
103        })
104        .catch((error) => {
105          console.log(error);
106        });
107    },
108    getUpdateServiceSettings({ commit }) {
109      api
110        .get('/redfish/v1/UpdateService')
111        .then(({ data }) => {
112          const applyTime =
113            data.HttpPushUriOptions.HttpPushUriApplyTime.ApplyTime;
114          const allowableActions =
115            data?.Actions?.['#UpdateService.SimpleUpdate']?.[
116              'TransferProtocol@Redfish.AllowableValues'
117            ];
118          commit('setApplyTime', applyTime);
119          const httpPushUri = data.HttpPushUri;
120          commit('setHttpPushUri', httpPushUri);
121          if (allowableActions?.includes('TFTP')) {
122            commit('setTftpUploadAvailable', true);
123          }
124        })
125        .catch((error) => console.log(error));
126    },
127    async uploadFirmware({ state }, image) {
128      return await api
129        .post(state.httpPushUri, image, {
130          headers: { 'Content-Type': 'application/octet-stream' },
131        })
132        .catch((error) => {
133          console.log(error);
134          throw new Error(i18n.t('pageFirmware.toast.errorUpdateFirmware'));
135        });
136    },
137    async uploadFirmwareTFTP(fileAddress) {
138      const data = {
139        TransferProtocol: 'TFTP',
140        ImageURI: fileAddress,
141      };
142      return await api
143        .post(
144          '/redfish/v1/UpdateService/Actions/UpdateService.SimpleUpdate',
145          data,
146        )
147        .catch((error) => {
148          console.log(error);
149          throw new Error(i18n.t('pageFirmware.toast.errorUpdateFirmware'));
150        });
151    },
152    async switchBmcFirmwareAndReboot({ getters }) {
153      const backupLocation = getters.backupBmcFirmware.location;
154      const data = {
155        Links: {
156          ActiveSoftwareImage: {
157            '@odata.id': backupLocation,
158          },
159        },
160      };
161      return await api
162        .patch(`${await this.dispatch('global/getBmcPath')}`, data)
163        .catch((error) => {
164          console.log(error);
165          throw new Error(i18n.t('pageFirmware.toast.errorSwitchImages'));
166        });
167    },
168  },
169};
170
171export default FirmwareStore;
172