1import api from '@/store/api';
2import i18n from '@/i18n';
3
4const NetworkStore = {
5  namespaced: true,
6  state: {
7    ethernetData: [],
8    firstInterfaceId: '', //used for setting global DHCP settings
9    globalNetworkSettings: [],
10    selectedInterfaceId: '', // which tab is selected
11    selectedInterfaceIndex: 0, // which tab is selected
12  },
13  getters: {
14    ethernetData: (state) => state.ethernetData,
15    firstInterfaceId: (state) => state.firstInterfaceId,
16    globalNetworkSettings: (state) => state.globalNetworkSettings,
17    selectedInterfaceId: (state) => state.selectedInterfaceId,
18    selectedInterfaceIndex: (state) => state.selectedInterfaceIndex,
19  },
20  mutations: {
21    setDomainNameState: (state, domainState) =>
22      (state.domainState = domainState),
23    setDnsState: (state, dnsState) => (state.dnsState = dnsState),
24    setEthernetData: (state, ethernetData) =>
25      (state.ethernetData = ethernetData),
26    setFirstInterfaceId: (state, firstInterfaceId) =>
27      (state.firstInterfaceId = firstInterfaceId),
28    setGlobalNetworkSettings: (state, data) => {
29      state.globalNetworkSettings = data.map(({ data }) => {
30        const {
31          DHCPv4,
32          DHCPv6,
33          HostName,
34          IPv4Addresses,
35          IPv4StaticAddresses,
36          IPv6Addresses,
37          IPv6StaticAddresses,
38          LinkStatus,
39          MACAddress,
40          IPv6DefaultGateway,
41        } = data;
42        return {
43          defaultGateway: IPv4StaticAddresses[0]?.Gateway, //First static gateway is the default gateway
44          ipv6DefaultGateway: IPv6DefaultGateway,
45          dhcpAddress: IPv4Addresses.filter(
46            (ipv4) => ipv4.AddressOrigin === 'DHCP',
47          ),
48          dhcpv6Address: IPv6Addresses.filter(
49            (ipv6) =>
50              ipv6.AddressOrigin === 'SLAAC' || ipv6.AddressOrigin === 'DHCPv6',
51          ),
52          dhcpEnabled: DHCPv4.DHCPEnabled,
53          dhcp6Enabled: DHCPv6.OperatingMode,
54          hostname: HostName,
55          macAddress: MACAddress,
56          linkStatus: LinkStatus,
57          staticAddress: IPv4StaticAddresses[0]?.Address, // Display first static address on overview page
58          ipv6StaticAddress: IPv6StaticAddresses[0]?.Address,
59          useDnsEnabled: DHCPv4.UseDNSServers,
60          useDomainNameEnabled: DHCPv4.UseDomainName,
61          useNtpEnabled: DHCPv4.UseNTPServers,
62          useDnsEnabledIpv6: DHCPv6.UseDNSServers,
63          useDomainNameEnabledIpv6: DHCPv6.UseDomainName,
64          useNtpEnabledIpv6: DHCPv6.UseNTPServers,
65        };
66      });
67    },
68    setNtpState: (state, ntpState) => (state.ntpState = ntpState),
69    setDomainNameStateIpv6: (state, domainState) =>
70      (state.domainStateIpv6 = domainState),
71    setDnsStateIpv6: (state, dnsState) => (state.dnsStateIpv6 = dnsState),
72    setNtpStateIpv6: (state, ntpState) => (state.ntpStateIpv6 = ntpState),
73    setSelectedInterfaceId: (state, selectedInterfaceId) =>
74      (state.selectedInterfaceId = selectedInterfaceId),
75    setSelectedInterfaceIndex: (state, selectedInterfaceIndex) =>
76      (state.selectedInterfaceIndex = selectedInterfaceIndex),
77  },
78  actions: {
79    async getEthernetData({ commit }) {
80      return await api
81        .get(`${await this.dispatch('global/getBmcPath')}/EthernetInterfaces`)
82        .then((response) =>
83          response.data.Members.map(
84            (ethernetInterface) => ethernetInterface['@odata.id'],
85          ),
86        )
87        .then((ethernetInterfaceIds) =>
88          api.all(
89            ethernetInterfaceIds.map((ethernetInterface) =>
90              api.get(ethernetInterface),
91            ),
92          ),
93        )
94        .then((ethernetInterfaces) => {
95          const ethernetData = ethernetInterfaces.map(
96            (ethernetInterface) => ethernetInterface.data,
97          );
98          const firstInterfaceId = ethernetData[0].Id;
99
100          commit('setEthernetData', ethernetData);
101          commit('setFirstInterfaceId', firstInterfaceId);
102          commit('setSelectedInterfaceId', firstInterfaceId);
103          commit('setGlobalNetworkSettings', ethernetInterfaces);
104        })
105        .catch((error) => {
106          console.log('Network Data:', error);
107        });
108    },
109    async saveDhcpEnabledState({ state, dispatch }, dhcpState) {
110      const data = {
111        DHCPv4: {
112          DHCPEnabled: dhcpState,
113        },
114      };
115      return api
116        .patch(
117          `${await this.dispatch('global/getBmcPath')}/EthernetInterfaces/${state.selectedInterfaceId}`,
118          data,
119        )
120        .then(dispatch('getEthernetData'))
121        .then(() => {
122          return i18n.global.t('pageNetwork.toast.successSaveNetworkSettings', {
123            setting: i18n.global.t('pageNetwork.dhcp'),
124          });
125        })
126        .catch((error) => {
127          console.log(error);
128          throw new Error(
129            i18n.global.t('pageNetwork.toast.errorSaveNetworkSettings', {
130              setting: i18n.global.t('pageNetwork.dhcp'),
131            }),
132          );
133        });
134    },
135    async saveDhcp6EnabledState({ state, dispatch }, dhcpState) {
136      const data = {
137        DHCPv6: {
138          OperatingMode: dhcpState ? 'Enabled' : 'Disabled',
139        },
140      };
141      return api
142        .patch(
143          `${await this.dispatch('global/getBmcPath')}/EthernetInterfaces/${state.selectedInterfaceId}`,
144          data,
145        )
146        .then(dispatch('getEthernetData'))
147        .then(() => {
148          return i18n.global.t('pageNetwork.toast.successSaveNetworkSettings', {
149            setting: i18n.global.t('pageNetwork.dhcp6'),
150          });
151        })
152        .catch((error) => {
153          console.log(error);
154          throw new Error(
155            i18n.global.t('pageNetwork.toast.errorSaveNetworkSettings', {
156              setting: i18n.global.t('pageNetwork.dhcp6'),
157            }),
158          );
159        });
160    },
161    async saveDomainNameState({ commit, state }, { domainState, ipVersion }) {
162      var data;
163      if (ipVersion === 'IPv4') {
164        commit('setDomainNameState', domainState);
165        data = {
166          DHCPv4: {
167            UseDomainName: domainState,
168          },
169        };
170      } else if (ipVersion === 'IPv6') {
171        commit('setDomainNameStateIpv6', domainState);
172        data = {
173          DHCPv6: {
174            UseDomainName: domainState,
175          },
176        };
177      }
178      // Saving to the first interface automatically updates DHCPv4 and DHCPv6
179      // on all interfaces
180      return api
181        .patch(
182          `${await this.dispatch('global/getBmcPath')}/EthernetInterfaces/${state.firstInterfaceId}`,
183          data,
184        )
185        .then(() => {
186          return i18n.global.t('pageNetwork.toast.successSaveNetworkSettings', {
187            setting: i18n.global.t('pageNetwork.domainName'),
188          });
189        })
190        .catch((error) => {
191          console.log(error);
192          if (ipVersion === 'IPv4') commit('setDomainNameState', !domainState);
193          else if (ipVersion === 'IPv6')
194            commit('setDomainNameStateIpv6', !domainState);
195          throw new Error(
196            i18n.global.t('pageNetwork.toast.errorSaveNetworkSettings', {
197              setting: i18n.global.t('pageNetwork.domainName'),
198            }),
199          );
200        });
201    },
202    async saveDnsState({ commit, state }, { dnsState, ipVersion }) {
203      var data;
204      if (ipVersion === 'IPv4') {
205        commit('setDnsState', dnsState);
206        data = {
207          DHCPv4: {
208            UseDNSServers: dnsState,
209          },
210        };
211      } else if (ipVersion === 'IPv6') {
212        commit('setDnsStateIpv6', dnsState);
213        data = {
214          DHCPv6: {
215            UseDNSServers: dnsState,
216          },
217        };
218      }
219      // Saving to the first interface automatically updates DHCPv4 and DHCPv6
220      // on all interfaces
221      return api
222        .patch(
223          `${await this.dispatch('global/getBmcPath')}/EthernetInterfaces/${state.firstInterfaceId}`,
224          data,
225        )
226        .then(() => {
227          return i18n.global.t('pageNetwork.toast.successSaveNetworkSettings', {
228            setting: i18n.global.t('pageNetwork.dns'),
229          });
230        })
231        .catch((error) => {
232          console.log(error);
233          if (ipVersion === 'IPv4') commit('setDnsState', !dnsState);
234          else if (ipVersion === 'IPv6') commit('setDnsStateIpv6', !dnsState);
235          throw new Error(
236            i18n.global.t('pageNetwork.toast.errorSaveNetworkSettings', {
237              setting: i18n.global.t('pageNetwork.dns'),
238            }),
239          );
240        });
241    },
242    async saveNtpState({ commit, state }, { ntpState, ipVersion }) {
243      var data;
244      if (ipVersion === 'IPv4') {
245        commit('setNtpState', ntpState);
246        data = {
247          DHCPv4: {
248            UseNTPServers: ntpState,
249          },
250        };
251      } else if (ipVersion === 'IPv6') {
252        commit('setNtpStateIpv6', ntpState);
253        data = {
254          DHCPv6: {
255            UseNTPServers: ntpState,
256          },
257        };
258      }
259      // Saving to the first interface automatically updates DHCPv4 and DHCPv6
260      // on all interfaces
261      return api
262        .patch(
263          `${await this.dispatch('global/getBmcPath')}/EthernetInterfaces/${state.firstInterfaceId}`,
264          data,
265        )
266        .then(() => {
267          return i18n.global.t('pageNetwork.toast.successSaveNetworkSettings', {
268            setting: i18n.global.t('pageNetwork.ntp'),
269          });
270        })
271        .catch((error) => {
272          console.log(error);
273          if (ipVersion === 'IPv4') commit('setNtpState', !ntpState);
274          else if (ipVersion === 'IPv6') commit('setNtpStateIpv6', !ntpState);
275          throw new Error(
276            i18n.global.t('pageNetwork.toast.errorSaveNetworkSettings', {
277              setting: i18n.global.t('pageNetwork.ntp'),
278            }),
279          );
280        });
281    },
282    async setSelectedTabIndex({ commit }, tabIndex) {
283      commit('setSelectedInterfaceIndex', tabIndex);
284    },
285    async setSelectedTabId({ commit }, tabId) {
286      commit('setSelectedInterfaceId', tabId);
287    },
288    async saveIpv4Address({ dispatch, state }, ipv4Form) {
289      const originalAddresses = state.ethernetData[
290        state.selectedInterfaceIndex
291      ].IPv4StaticAddresses.map((ipv4) => {
292        const { Address, SubnetMask, Gateway } = ipv4;
293        return {
294          Address,
295          SubnetMask,
296          Gateway,
297        };
298      });
299      const newAddress = [ipv4Form];
300      return api
301        .patch(
302          `${await this.dispatch('global/getBmcPath')}/EthernetInterfaces/${state.selectedInterfaceId}`,
303          { IPv4StaticAddresses: originalAddresses.concat(newAddress) },
304        )
305        .then(dispatch('getEthernetData'))
306        .then(() => {
307          return i18n.global.t('pageNetwork.toast.successSaveNetworkSettings', {
308            setting: i18n.global.t('pageNetwork.ipv4'),
309          });
310        })
311        .catch((error) => {
312          console.log(error);
313          throw new Error(
314            i18n.global.t('pageNetwork.toast.errorSaveNetworkSettings', {
315              setting: i18n.global.t('pageNetwork.ipv4'),
316            }),
317          );
318        });
319    },
320    async saveIpv6Address({ dispatch, state }, ipv6Form) {
321      const originalAddresses = state.ethernetData[
322        state.selectedInterfaceIndex
323      ].IPv6StaticAddresses.map((ipv6) => {
324        const { Address, PrefixLength } = ipv6;
325        return {
326          Address,
327          PrefixLength,
328        };
329      });
330      const newAddress = [ipv6Form];
331      return api
332        .patch(
333          `${await this.dispatch('global/getBmcPath')}/EthernetInterfaces/${state.selectedInterfaceId}`,
334          { IPv6StaticAddresses: originalAddresses.concat(newAddress) },
335        )
336        .then(dispatch('getEthernetData'))
337        .then(() => {
338          return i18n.global.t('pageNetwork.toast.successSaveNetworkSettings', {
339            setting: i18n.global.t('pageNetwork.ipv6'),
340          });
341        })
342        .catch((error) => {
343          console.log(error);
344          throw new Error(
345            i18n.global.t('pageNetwork.toast.errorSaveNetworkSettings', {
346              setting: i18n.global.t('pageNetwork.ipv6'),
347            }),
348          );
349        });
350    },
351    async editIpv4Address({ dispatch, state }, ipv4TableData) {
352      return api
353        .patch(
354          `${await this.dispatch('global/getBmcPath')}/EthernetInterfaces/${state.selectedInterfaceId}`,
355          { IPv4StaticAddresses: ipv4TableData },
356        )
357        .then(dispatch('getEthernetData'))
358        .then(() => {
359          return i18n.global.t('pageNetwork.toast.successSaveNetworkSettings', {
360            setting: i18n.global.t('pageNetwork.ipv4'),
361          });
362        })
363        .catch((error) => {
364          console.log(error);
365          throw new Error(
366            i18n.global.t('pageNetwork.toast.errorSaveNetworkSettings', {
367              setting: i18n.global.t('pageNetwork.ipv4'),
368            }),
369          );
370        });
371    },
372    async editIpv6Address({ dispatch, state }, ipv6TableData) {
373      return api
374        .patch(
375          `${await this.dispatch('global/getBmcPath')}/EthernetInterfaces/${state.selectedInterfaceId}`,
376          { IPv6StaticAddresses: ipv6TableData },
377        )
378        .then(dispatch('getEthernetData'))
379        .then(() => {
380          return i18n.global.t('pageNetwork.toast.successSaveNetworkSettings', {
381            setting: i18n.global.t('pageNetwork.ipv6'),
382          });
383        })
384        .catch((error) => {
385          console.log(error);
386          throw new Error(
387            i18n.global.t('pageNetwork.toast.errorSaveNetworkSettings', {
388              setting: i18n.global.t('pageNetwork.ipv6'),
389            }),
390          );
391        });
392    },
393    async saveSettings({ state, dispatch }, interfaceSettingsForm) {
394      return api
395        .patch(
396          `${await this.dispatch('global/getBmcPath')}/EthernetInterfaces/${state.selectedInterfaceId}`,
397          interfaceSettingsForm,
398        )
399        .then(dispatch('getEthernetData'))
400        .then(() => {
401          return i18n.global.t('pageNetwork.toast.successSaveNetworkSettings', {
402            setting: i18n.global.t('pageNetwork.network'),
403          });
404        })
405        .catch((error) => {
406          console.log(error);
407          throw new Error(
408            i18n.global.t('pageNetwork.toast.errorSaveNetworkSettings', {
409              setting: i18n.global.t('pageNetwork.network'),
410            }),
411          );
412        });
413    },
414    async saveDnsAddress({ dispatch, state }, dnsForm) {
415      const newAddress = dnsForm;
416      const originalAddresses =
417        state.ethernetData[state.selectedInterfaceIndex].StaticNameServers;
418      const newDnsArray = originalAddresses.concat(newAddress);
419      return api
420        .patch(
421          `${await this.dispatch('global/getBmcPath')}/EthernetInterfaces/${state.selectedInterfaceId}`,
422          { StaticNameServers: newDnsArray },
423        )
424        .then(dispatch('getEthernetData'))
425        .then(() => {
426          return i18n.global.t('pageNetwork.toast.successSaveNetworkSettings', {
427            setting: i18n.global.t('pageNetwork.dns'),
428          });
429        })
430        .catch((error) => {
431          console.log(error);
432          throw new Error(
433            i18n.global.t('pageNetwork.toast.errorSaveNetworkSettings', {
434              setting: i18n.global.t('pageNetwork.dns'),
435            }),
436          );
437        });
438    },
439    async editDnsAddress({ dispatch, state }, dnsTableData) {
440      return api
441        .patch(
442          `${await this.dispatch('global/getBmcPath')}/EthernetInterfaces/${state.selectedInterfaceId}`,
443          { StaticNameServers: dnsTableData },
444        )
445        .then(dispatch('getEthernetData'))
446        .then(() => {
447          return i18n.global.t('pageNetwork.toast.successSaveNetworkSettings', {
448            setting: i18n.global.t('pageNetwork.dns'),
449          });
450        })
451        .catch((error) => {
452          console.log(error);
453          throw new Error(
454            i18n.global.t('pageNetwork.toast.errorSaveNetworkSettings', {
455              setting: i18n.global.t('pageNetwork.dns'),
456            }),
457          );
458        });
459    },
460  },
461};
462
463export default NetworkStore;
464