diff options
Diffstat (limited to 'src/store')
-rw-r--r-- | src/store/modules/GlobalStore.js | 26 | ||||
-rw-r--r-- | src/store/modules/Operations/VirtualMediaStore.js | 144 | ||||
-rw-r--r-- | src/store/modules/SecurityAndAccess/PoliciesStore.js | 44 |
3 files changed, 208 insertions, 6 deletions
diff --git a/src/store/modules/GlobalStore.js b/src/store/modules/GlobalStore.js index 262d1163..3f512087 100644 --- a/src/store/modules/GlobalStore.js +++ b/src/store/modules/GlobalStore.js @@ -7,6 +7,14 @@ const HOST_STATE = { diagnosticMode: 'xyz.openbmc_project.State.Host.HostState.DiagnosticMode', }; +const convertTZ = (date, tzString) => { + return new Date( + (typeof date === 'string' ? new Date(date) : date).toLocaleString('en-US', { + timeZone: tzString, + }) + ); +}; + const serverStateMapper = (hostState) => { switch (hostState) { case HOST_STATE.on: @@ -37,6 +45,7 @@ const GlobalStore = { modelType: null, serialNumber: null, serverStatus: 'unreachable', + timeZone: localStorage.getItem('storedTimeZone'), languagePreference: localStorage.getItem('storedLanguage') || 'en-US', isUtcDisplay: localStorage.getItem('storedUtcDisplay') ? JSON.parse(localStorage.getItem('storedUtcDisplay')) @@ -52,6 +61,7 @@ const GlobalStore = { bmcTime: (state) => state.bmcTime, liveBmcTime: (state) => state.liveBmcTime, liveClock: (state) => state.liveClock, + timeZone: (state) => state.timeZone, languagePreference: (state) => state.languagePreference, isUtcDisplay: (state) => state.isUtcDisplay, username: (state) => state.username, @@ -65,6 +75,10 @@ const GlobalStore = { setBmcTime: (state, bmcTime) => (state.bmcTime = bmcTime), setLiveBmcTime: (state, liveBmcTime) => (state.liveBmcTime = liveBmcTime), setLiveClock: (state, liveClock) => (state.liveClock = liveClock), + setTimeZone: (state, timeZone) => { + state.timeZone = timeZone; + localStorage.setItem('storedTimeZone', timeZone); + }, setClockInterval: (state, clockInterval) => (state.clockInterval = clockInterval), setServerStatus: (state, serverState) => @@ -81,6 +95,9 @@ const GlobalStore = { }, }, actions: { + changeTimeZone({ commit }, timeZone) { + commit('setTimeZone', timeZone); + }, changeServerStatus({ commit, dispatch }, status) { commit('setServerStatus', status); @@ -112,13 +129,18 @@ const GlobalStore = { }, 1000); commit('setClockInterval', clockInterval); }, - async getBmcTime({ commit, dispatch }) { + async getBmcTime({ commit, dispatch, getters }) { + if (!getters.timeZone) { + commit('setTimeZone', '(UTC+3) Europe/Moscow'); + } + return await api .get('/redfish/v1/Managers/bmc') .then((response) => { const bmcDateTime = response.data.DateTime; const date = new Date(bmcDateTime); - commit('setBmcTime', date); + const timeZone = getters.timeZone.split(' ')[1]; + commit('setBmcTime', convertTZ(date, timeZone)); dispatch('initLiveClock'); }) .catch((error) => console.log(error)); diff --git a/src/store/modules/Operations/VirtualMediaStore.js b/src/store/modules/Operations/VirtualMediaStore.js index 3ae08a11..b9eefa2b 100644 --- a/src/store/modules/Operations/VirtualMediaStore.js +++ b/src/store/modules/Operations/VirtualMediaStore.js @@ -19,6 +19,13 @@ const VirtualMediaStore = { proxyDevices: [], legacyDevices: [], connections: [], + // VirtualMedia`s log shows some 90 secs timeout (nbd-client`s output) + // kernel log shows some ~90 secs timeout in ndb device driver + // Let`s use 2*60 secs. Experiments showed it is enough by the moment. + legacyDevicesTransitionStateInitialTimeout: 2 * 60, + legacyDevicesTransitionStateZeroTimeout: 0, + legacyDevicesTransitionStatePollInterval: 1, + legacyDevicesTransitionStateTimerId: null, }, getters: { proxyDevices: (state) => state.proxyDevices, @@ -29,9 +36,26 @@ const VirtualMediaStore = { (state.proxyDevices = deviceData), setLegacyDevicesData: (state, deviceData) => (state.legacyDevices = deviceData), + setLegacyDevicesTransitionStateTimerId: (state, newTimerId) => { + if (state.legacyDevicesTransitionStateTimerId != null) { + clearTimeout(state.legacyDevicesTransitionStateTimerId); + } + state.legacyDevicesTransitionStateTimerId = newTimerId; + }, + patchLegacyDevice: (state, devicePatch) => { + state.legacyDevices = state.legacyDevices.map((device) => { + if (device.id === devicePatch.id) { + device = { + ...device, + ...devicePatch, + }; + } + return device; + }); + }, }, actions: { - async getData({ commit }) { + async getData({ commit, state }) { const virtualMediaListEnabled = process.env.VUE_APP_VIRTUAL_MEDIA_LIST_ENABLED === 'true' ? true @@ -43,6 +67,7 @@ const VirtualMediaStore = { file: null, transferProtocolType: transferProtocolType.OEM, isActive: false, + isConnected: undefined, }; commit('setProxyDevicesData', [device]); return; @@ -56,12 +81,30 @@ const VirtualMediaStore = { .then((devices) => api.all(devices.map((device) => api.get(device)))) .then((devices) => { const deviceData = devices.map((device) => { + const id = device.data?.Id; const isActive = device.data?.Inserted === true ? true : false; + const isConnected = device.data?.ConnectedVia !== undefined; + let serverUri = device.data?.Image; + let isRW = device.data?.WriteProtected === false ? true : false; + if (serverUri === undefined) { + const device = state.legacyDevices.find( + (device) => device.id === id + ); + if (device !== undefined) { + serverUri = device.serverUri; + isRW = device.isRW; + } else { + serverUri = ''; + } + } return { - id: device.data?.Id, + id: id, transferProtocolType: device.data?.TransferProtocolType, websocket: device.data?.Oem?.OpenBMC?.WebSocketEndpoint, isActive: isActive, + isConnected: isConnected, + serverUri: serverUri, + isRW: isRW, }; }); const proxyDevices = deviceData @@ -75,14 +118,24 @@ const VirtualMediaStore = { const legacyDevices = deviceData .filter((d) => d.transferProtocolType !== transferProtocolType.OEM) .map((device) => { + let newTimeout = state.legacyDevicesTransitionStateZeroTimeout; + if (device.isConnected && !device.isActive) { + this.dispatch( + 'virtualMedia/pollLegacyDevicesTransitionState', + device.id + ); + // re-commit the state + newTimeout = state.legacyDevicesTransitionStateInitialTimeout; + } return { ...device, - serverUri: '', username: '', password: '', - isRW: false, + legacyDeviceTransitionStateTimeout: newTimeout, }; }); + proxyDevices.sort((a, b) => a.id.localeCompare(b.id)); + legacyDevices.sort((a, b) => a.id.localeCompare(b.id)); commit('setProxyDevicesData', proxyDevices); commit('setLegacyDevicesData', legacyDevices); }) @@ -90,12 +143,92 @@ const VirtualMediaStore = { console.log('Virtual Media:', error); }); }, + async getLegacyDeviceData({ commit, state }, id) { + const device = state.legacyDevices.find((device) => device.id === id); + let newTimeout = device.legacyDeviceTransitionStateTimeout - 1; + if ( + device.legacyDeviceTransitionStateTimeout % + state.legacyDevicesTransitionStatePollInterval != + 0 + ) { + const devicePatch = { + id: id, + legacyDeviceTransitionStateTimeout: newTimeout, + }; + commit('patchLegacyDevice', devicePatch); + return; + } + return await api + .get(`/redfish/v1/Managers/bmc/VirtualMedia/${id}`) + .then((response) => { + if (response.data?.Id !== id) { + console.log( + `VirtualMedia: Error: expected_id=${id}, actual_id=${response.data?.Id}` + ); + } + const isActive = response.data?.Inserted === true ? true : false; + const isConnected = response.data?.ConnectedVia !== undefined; + if (!(isConnected && !isActive)) { + newTimeout = device.legacyDevicesTransitionStateZeroTimeout - 1; + } + const devicePatch = { + id: id, + isActive: isActive, + isConnected: isConnected, + legacyDeviceTransitionStateTimeout: newTimeout, + }; + commit('patchLegacyDevice', devicePatch); + }) + .catch((error) => { + console.log('Virtual Media:', error); + }); + }, + async pollLegacyDevicesTransitionState({ commit, state }, id = undefined) { + let needRescheduling = false; + if (id !== undefined) { + const devicePatch = { + id: id, + isConnected: true, + isActive: false, + legacyDeviceTransitionStateTimeout: + state.legacyDevicesTransitionStateInitialTimeout, + }; + commit('patchLegacyDevice', devicePatch); + needRescheduling = true; + } else { + const devicesCount = state.legacyDevices + .filter((device) => { + return ( + device.isConnected && + !device.isActive && + device.legacyDeviceTransitionStateTimeout > + state.legacyDevicesTransitionStateZeroTimeout + ); + }) + .map((device) => { + this.dispatch('virtualMedia/getLegacyDeviceData', device.id); + }) + .reduce((previous) => previous + 1, 0); + needRescheduling = devicesCount > 0; + } + let newRescheduleTimerId = null; + if (needRescheduling) { + const pollTimeout = 1 * 1000; + newRescheduleTimerId = setTimeout(() => { + this.dispatch('virtualMedia/pollLegacyDevicesTransitionState'); + }, pollTimeout); + } + commit('setLegacyDevicesTransitionStateTimerId', newRescheduleTimerId); + }, async mountImage(_, { id, data }) { return await api .post( `/redfish/v1/Managers/bmc/VirtualMedia/${id}/Actions/VirtualMedia.InsertMedia`, data ) + .then(() => { + this.dispatch('virtualMedia/pollLegacyDevicesTransitionState', id); + }) .catch((error) => { console.log('Mount image:', error); throw new Error(); @@ -106,6 +239,9 @@ const VirtualMediaStore = { .post( `/redfish/v1/Managers/bmc/VirtualMedia/${id}/Actions/VirtualMedia.EjectMedia` ) + .then(() => { + this.dispatch('virtualMedia/pollLegacyDevicesTransitionState', id); + }) .catch((error) => { console.log('Unmount image:', error); throw new Error(); diff --git a/src/store/modules/SecurityAndAccess/PoliciesStore.js b/src/store/modules/SecurityAndAccess/PoliciesStore.js index 64bd3369..cd582195 100644 --- a/src/store/modules/SecurityAndAccess/PoliciesStore.js +++ b/src/store/modules/SecurityAndAccess/PoliciesStore.js @@ -5,21 +5,27 @@ const PoliciesStore = { namespaced: true, state: { sshProtocolEnabled: false, + sshPort: null, ipmiProtocolEnabled: false, + ipmiPort: null, rtadEnabled: 'Disabled', vtpmEnabled: 'Disabled', }, getters: { sshProtocolEnabled: (state) => state.sshProtocolEnabled, + sshPort: (state) => state.sshPort, ipmiProtocolEnabled: (state) => state.ipmiProtocolEnabled, + ipmiPort: (state) => state.ipmiPort, rtadEnabled: (state) => state.rtadEnabled, vtpmEnabled: (state) => state.vtpmEnabled, }, mutations: { setSshProtocolEnabled: (state, sshProtocolEnabled) => (state.sshProtocolEnabled = sshProtocolEnabled), + setSshPort: (state, sshPort) => (state.sshPort = sshPort), setIpmiProtocolEnabled: (state, ipmiProtocolEnabled) => (state.ipmiProtocolEnabled = ipmiProtocolEnabled), + setIpmiPort: (state, ipmiPort) => (state.ipmiPort = ipmiPort), setRtadEnabled: (state, rtadEnabled) => (state.rtadEnabled = rtadEnabled), setVtpmEnabled: (state, vtpmEnabled) => (state.vtpmEnabled = vtpmEnabled), }, @@ -29,9 +35,13 @@ const PoliciesStore = { .get('/redfish/v1/Managers/bmc/NetworkProtocol') .then((response) => { const sshProtocol = response.data.SSH.ProtocolEnabled; + const sshPort = response.data.SSH.Port; const ipmiProtocol = response.data.IPMI.ProtocolEnabled; + const ipmiPort = response.data.IPMI.Port; commit('setSshProtocolEnabled', sshProtocol); + commit('setSshPort', sshPort); commit('setIpmiProtocolEnabled', ipmiProtocol); + commit('setIpmiPort', ipmiPort); }) .catch((error) => console.log(error)); }, @@ -96,6 +106,40 @@ const PoliciesStore = { } }); }, + async saveSshPort({ commit }, port) { + const ssh = { + SSH: { + Port: +port, + }, + }; + return await api + .patch('/redfish/v1/Managers/bmc/NetworkProtocol', ssh) + .then(() => { + commit('setSshPort', port); + return i18n.t('pagePolicies.toast.successSshPort'); + }) + .catch((error) => { + console.log(error); + throw new Error(i18n.t('pagePolicies.toast.errorSshPort')); + }); + }, + async saveIpmiPort({ commit }, port) { + const ipmi = { + IPMI: { + Port: +port, + }, + }; + return await api + .patch('/redfish/v1/Managers/bmc/NetworkProtocol', ipmi) + .then(() => { + commit('setSshPort', port); + return i18n.t('pagePolicies.toast.successIpmiPort'); + }) + .catch((error) => { + console.log(error); + throw new Error(i18n.t('pagePolicies.toast.errorIpmiPort')); + }); + }, async saveRtadState({ commit }, updatedRtad) { commit('setRtadEnabled', updatedRtad); return await api |