From 7affc529b7fba41193c4d48764707e9961cdd22d Mon Sep 17 00:00:00 2001 From: Sandeepa Singh Date: Tue, 6 Jul 2021 16:29:10 +0530 Subject: IA update: Update health section This is the second update to information architecture changes and has the following changes: - Health section is updated to hardware status section - Hardware status page is updated to inventory and LEDs page - Route for sensors page has been updated Signed-off-by: Sandeepa Singh Change-Id: Ia1ba3a15a243a00f59a2ec646132436eb355a999 --- src/store/modules/HardwareStatus/BmcStore.js | 79 +++++++++++++ src/store/modules/HardwareStatus/ChassisStore.js | 89 +++++++++++++++ src/store/modules/HardwareStatus/FanStore.js | 50 +++++++++ src/store/modules/HardwareStatus/MemoryStore.js | 39 +++++++ .../modules/HardwareStatus/PowerSupplyStore.js | 78 +++++++++++++ src/store/modules/HardwareStatus/ProcessorStore.js | 104 +++++++++++++++++ src/store/modules/HardwareStatus/SensorsStore.js | 123 +++++++++++++++++++++ src/store/modules/HardwareStatus/ServerLedStore.js | 55 +++++++++ src/store/modules/HardwareStatus/SystemStore.js | 72 ++++++++++++ 9 files changed, 689 insertions(+) create mode 100644 src/store/modules/HardwareStatus/BmcStore.js create mode 100644 src/store/modules/HardwareStatus/ChassisStore.js create mode 100644 src/store/modules/HardwareStatus/FanStore.js create mode 100644 src/store/modules/HardwareStatus/MemoryStore.js create mode 100644 src/store/modules/HardwareStatus/PowerSupplyStore.js create mode 100644 src/store/modules/HardwareStatus/ProcessorStore.js create mode 100644 src/store/modules/HardwareStatus/SensorsStore.js create mode 100644 src/store/modules/HardwareStatus/ServerLedStore.js create mode 100644 src/store/modules/HardwareStatus/SystemStore.js (limited to 'src/store/modules/HardwareStatus') diff --git a/src/store/modules/HardwareStatus/BmcStore.js b/src/store/modules/HardwareStatus/BmcStore.js new file mode 100644 index 00000000..f58dc635 --- /dev/null +++ b/src/store/modules/HardwareStatus/BmcStore.js @@ -0,0 +1,79 @@ +import api from '@/store/api'; +import i18n from '@/i18n'; + +const BmcStore = { + namespaced: true, + state: { + bmc: null, + }, + getters: { + bmc: (state) => state.bmc, + }, + mutations: { + setBmcInfo: (state, data) => { + const bmc = {}; + bmc.dateTime = new Date(data.DateTime); + bmc.description = data.Description; + bmc.firmwareVersion = data.FirmwareVersion; + bmc.graphicalConsoleConnectTypes = + data.GraphicalConsole.ConnectTypesSupported; + bmc.graphicalConsoleEnabled = data.GraphicalConsole.ServiceEnabled; + bmc.graphicalConsoleMaxSessions = + data.GraphicalConsole.MaxConcurrentSessions; + bmc.health = data.Status.Health; + bmc.healthRollup = data.Status.HealthRollup; + bmc.id = data.Id; + bmc.lastResetTime = new Date(data.LastResetTime); + bmc.identifyLed = data.LocationIndicatorActive; + bmc.locationNumber = data.LocationNumber; + bmc.manufacturer = data.manufacturer; + bmc.managerType = data.ManagerType; + bmc.model = data.Model; + bmc.name = data.Name; + bmc.partNumber = data.PartNumber; + bmc.powerState = data.PowerState; + bmc.serialConsoleConnectTypes = data.SerialConsole.ConnectTypesSupported; + bmc.serialConsoleEnabled = data.SerialConsole.ServiceEnabled; + bmc.serialConsoleMaxSessions = data.SerialConsole.MaxConcurrentSessions; + bmc.serialNumber = data.SerialNumber; + bmc.serviceEntryPointUuid = data.ServiceEntryPointUUID; + bmc.sparePartNumber = data.SparePartNumber; + bmc.statusState = data.Status.State; + bmc.uuid = data.UUID; + bmc.uri = data['@odata.id']; + state.bmc = bmc; + }, + }, + actions: { + async getBmcInfo({ commit }) { + return await api + .get('/redfish/v1/Managers/bmc') + .then(({ data }) => commit('setBmcInfo', data)) + .catch((error) => console.log(error)); + }, + async updateIdentifyLedValue({ dispatch }, led) { + const uri = led.uri; + const updatedIdentifyLedValue = { + LocationIndicatorActive: led.identifyLed, + }; + return await api + .patch(uri, updatedIdentifyLedValue) + .then(() => dispatch('getBmcInfo')) + .catch((error) => { + dispatch('getBmcInfo'); + console.log('error', error); + if (led.identifyLed) { + throw new Error( + i18n.t('pageInventory.toast.errorEnableIdentifyLed') + ); + } else { + throw new Error( + i18n.t('pageInventory.toast.errorDisableIdentifyLed') + ); + } + }); + }, + }, +}; + +export default BmcStore; diff --git a/src/store/modules/HardwareStatus/ChassisStore.js b/src/store/modules/HardwareStatus/ChassisStore.js new file mode 100644 index 00000000..b5edef56 --- /dev/null +++ b/src/store/modules/HardwareStatus/ChassisStore.js @@ -0,0 +1,89 @@ +import api from '@/store/api'; +import i18n from '@/i18n'; + +const ChassisStore = { + namespaced: true, + state: { + chassis: [], + }, + getters: { + chassis: (state) => state.chassis, + }, + mutations: { + setChassisInfo: (state, data) => { + state.chassis = data.map((chassis) => { + const { + Id, + Status = {}, + PartNumber, + SerialNumber, + ChassisType, + Manufacturer, + PowerState, + LocationIndicatorActive, + AssetTag, + MaxPowerWatts, + MinPowerWatts, + Name, + } = chassis; + + return { + id: Id, + health: Status.Health, + partNumber: PartNumber, + serialNumber: SerialNumber, + chassisType: ChassisType, + manufacturer: Manufacturer, + powerState: PowerState, + statusState: Status.State, + healthRollup: Status.HealthRollup, + assetTag: AssetTag, + maxPowerWatts: MaxPowerWatts, + minPowerWatts: MinPowerWatts, + name: Name, + identifyLed: LocationIndicatorActive, + uri: chassis['@odata.id'], + }; + }); + }, + }, + actions: { + async getChassisInfo({ commit }) { + return await api + .get('/redfish/v1/Chassis') + .then(({ data: { Members = [] } }) => + Members.map((member) => api.get(member['@odata.id'])) + ) + .then((promises) => api.all(promises)) + .then((response) => { + const data = response.map(({ data }) => data); + commit('setChassisInfo', data); + }) + .catch((error) => console.log(error)); + }, + async updateIdentifyLedValue({ dispatch }, led) { + const uri = led.uri; + const updatedIdentifyLedValue = { + LocationIndicatorActive: led.identifyLed, + }; + return await api + .patch(uri, updatedIdentifyLedValue) + .then(() => dispatch('getChassisInfo')) + .catch((error) => { + dispatch('getChassisInfo'); + console.log('error', error); + if (led.identifyLed) { + throw new Error( + i18n.t('pageInventory.toast.errorEnableIdentifyLed') + ); + } else { + throw new Error( + i18n.t('pageInventory.toast.errorDisableIdentifyLed') + ); + } + }); + }, + }, +}; + +export default ChassisStore; diff --git a/src/store/modules/HardwareStatus/FanStore.js b/src/store/modules/HardwareStatus/FanStore.js new file mode 100644 index 00000000..fca1f326 --- /dev/null +++ b/src/store/modules/HardwareStatus/FanStore.js @@ -0,0 +1,50 @@ +import api from '@/store/api'; + +const FanStore = { + namespaced: true, + state: { + fans: [], + }, + getters: { + fans: (state) => state.fans, + }, + mutations: { + setFanInfo: (state, data) => { + state.fans = data.map((fan) => { + const { + IndicatorLED, + Location, + MemberId, + Name, + Reading, + ReadingUnits, + Status = {}, + PartNumber, + SerialNumber, + } = fan; + return { + id: MemberId, + health: Status.Health, + partNumber: PartNumber, + serialNumber: SerialNumber, + healthRollup: Status.HealthRollup, + identifyLed: IndicatorLED, + locationNumber: Location, + name: Name, + speed: Reading + ' ' + ReadingUnits, + statusState: Status.State, + }; + }); + }, + }, + actions: { + async getFanInfo({ commit }) { + return await api + .get('/redfish/v1/Chassis/chassis/Thermal') + .then(({ data: { Fans = [] } }) => commit('setFanInfo', Fans)) + .catch((error) => console.log(error)); + }, + }, +}; + +export default FanStore; diff --git a/src/store/modules/HardwareStatus/MemoryStore.js b/src/store/modules/HardwareStatus/MemoryStore.js new file mode 100644 index 00000000..cd2478de --- /dev/null +++ b/src/store/modules/HardwareStatus/MemoryStore.js @@ -0,0 +1,39 @@ +import api from '@/store/api'; + +const MemoryStore = { + namespaced: true, + state: { + dimms: [], + }, + getters: { + dimms: (state) => state.dimms, + }, + mutations: { + setMemoryInfo: (state, data) => { + state.dimms = data.map(({ data }) => { + const { Id, Status = {}, PartNumber, SerialNumber } = data; + return { + id: Id, + health: Status.Health, + partNumber: PartNumber, + serialNumber: SerialNumber, + statusState: Status.State, + }; + }); + }, + }, + actions: { + async getDimms({ commit }) { + return await api + .get('/redfish/v1/Systems/system/Memory') + .then(({ data: { Members } }) => { + const promises = Members.map((item) => api.get(item['@odata.id'])); + return api.all(promises); + }) + .then((response) => commit('setMemoryInfo', response)) + .catch((error) => console.log(error)); + }, + }, +}; + +export default MemoryStore; diff --git a/src/store/modules/HardwareStatus/PowerSupplyStore.js b/src/store/modules/HardwareStatus/PowerSupplyStore.js new file mode 100644 index 00000000..f7be2809 --- /dev/null +++ b/src/store/modules/HardwareStatus/PowerSupplyStore.js @@ -0,0 +1,78 @@ +import api from '@/store/api'; + +const PowerSupplyStore = { + namespaced: true, + state: { + powerSupplies: [], + }, + getters: { + powerSupplies: (state) => state.powerSupplies, + }, + mutations: { + setPowerSupply: (state, data) => { + state.powerSupplies = data.map((powerSupply) => { + const { + EfficiencyPercent, + FirmwareVersion, + LocationIndicatorActive, + MemberId, + Manufacturer, + Model, + Name, + PartNumber, + PowerInputWatts, + SerialNumber, + SparePartNumber, + Status = {}, + } = powerSupply; + return { + id: MemberId, + health: Status.Health, + partNumber: PartNumber, + serialNumber: SerialNumber, + efficiencyPercent: EfficiencyPercent, + firmwareVersion: FirmwareVersion, + identifyLed: LocationIndicatorActive, + manufacturer: Manufacturer, + model: Model, + powerInputWatts: PowerInputWatts, + name: Name, + sparePartNumber: SparePartNumber, + statusState: Status.State, + }; + }); + }, + }, + actions: { + async getChassisCollection() { + return await api + .get('/redfish/v1/Chassis') + .then(({ data: { Members } }) => + Members.map((member) => member['@odata.id']) + ) + .catch((error) => console.log(error)); + }, + async getAllPowerSupplies({ dispatch, commit }) { + const collection = await dispatch('getChassisCollection'); + if (!collection) return; + return await api + .all(collection.map((chassis) => dispatch('getChassisPower', chassis))) + .then((supplies) => { + let suppliesList = []; + supplies.forEach( + (supply) => (suppliesList = [...suppliesList, ...supply]) + ); + commit('setPowerSupply', suppliesList); + }) + .catch((error) => console.log(error)); + }, + async getChassisPower(_, id) { + return await api + .get(`${id}/Power`) + .then(({ data: { PowerSupplies } }) => PowerSupplies || []) + .catch((error) => console.log(error)); + }, + }, +}; + +export default PowerSupplyStore; diff --git a/src/store/modules/HardwareStatus/ProcessorStore.js b/src/store/modules/HardwareStatus/ProcessorStore.js new file mode 100644 index 00000000..c7cbbeea --- /dev/null +++ b/src/store/modules/HardwareStatus/ProcessorStore.js @@ -0,0 +1,104 @@ +import api from '@/store/api'; +import i18n from '@/i18n'; + +const ProcessorStore = { + namespaced: true, + state: { + processors: [], + }, + getters: { + processors: (state) => state.processors, + }, + mutations: { + setProcessorsInfo: (state, data) => { + state.processors = data.map((processor) => { + const { + Id, + Status = {}, + PartNumber, + SerialNumber, + SparePartNumber, + InstructionSet, + Manufacturer, + Model, + Name, + ProcessorArchitecture, + ProcessorType, + Version, + AssetTag, + MinSpeedMHz, + MaxSpeedMHz, + TotalCores, + TotalThreads, + LocationNumber, + LocationIndicatorActive, + } = processor; + return { + id: Id, + health: Status.Health, + healthRollup: Status.HealthRollup, + partNumber: PartNumber, + sparePartNumber: SparePartNumber, + serialNumber: SerialNumber, + statusState: Status.State, + instructionSet: InstructionSet, + manufacturer: Manufacturer, + model: Model, + name: Name, + processorArchitecture: ProcessorArchitecture, + processorType: ProcessorType, + version: Version, + assetTag: AssetTag, + minSpeedMHz: MinSpeedMHz, + maxSpeedMHz: MaxSpeedMHz, + totalCores: TotalCores, + totalThreads: TotalThreads, + locationNumber: LocationNumber, + identifyLed: LocationIndicatorActive, + uri: processor['@odata.id'], + }; + }); + }, + }, + actions: { + async getProcessorsInfo({ commit }) { + return await api + .get('/redfish/v1/Systems/system/Processors') + .then(({ data: { Members = [] } }) => + Members.map((member) => api.get(member['@odata.id'])) + ) + .then((promises) => api.all(promises)) + .then((response) => { + const data = response.map(({ data }) => data); + commit('setProcessorsInfo', data); + }) + .catch((error) => console.log(error)); + }, + // Waiting for the following to be merged to test the Identify Led: + // https://gerrit.openbmc-project.xyz/c/openbmc/bmcweb/+/37045 + async updateIdentifyLedValue({ dispatch }, led) { + const uri = led.uri; + const updatedIdentifyLedValue = { + LocationIndicatorActive: led.identifyLed, + }; + return await api + .patch(uri, updatedIdentifyLedValue) + .then(() => dispatch('getProcessorsInfo')) + .catch((error) => { + dispatch('getProcessorsInfo'); + console.log('error', error); + if (led.identifyLed) { + throw new Error( + i18n.t('pageInventory.toast.errorEnableIdentifyLed') + ); + } else { + throw new Error( + i18n.t('pageInventory.toast.errorDisableIdentifyLed') + ); + } + }); + }, + }, +}; + +export default ProcessorStore; diff --git a/src/store/modules/HardwareStatus/SensorsStore.js b/src/store/modules/HardwareStatus/SensorsStore.js new file mode 100644 index 00000000..0af2a95b --- /dev/null +++ b/src/store/modules/HardwareStatus/SensorsStore.js @@ -0,0 +1,123 @@ +import api from '@/store/api'; +import { uniqBy } from 'lodash'; + +const SensorsStore = { + namespaced: true, + state: { + sensors: [], + }, + getters: { + sensors: (state) => state.sensors, + }, + mutations: { + setSensors: (state, sensors) => { + state.sensors = uniqBy([...state.sensors, ...sensors], 'name'); + }, + }, + actions: { + async getAllSensors({ dispatch }) { + const collection = await dispatch('getChassisCollection'); + if (!collection) return; + const promises = collection.reduce((acc, id) => { + acc.push(dispatch('getSensors', id)); + acc.push(dispatch('getThermalSensors', id)); + acc.push(dispatch('getPowerSensors', id)); + return acc; + }, []); + return await api.all(promises); + }, + async getChassisCollection() { + return await api + .get('/redfish/v1/Chassis') + .then(({ data: { Members } }) => + Members.map((member) => member['@odata.id']) + ) + .catch((error) => console.log(error)); + }, + async getSensors({ commit }, id) { + const sensors = await api + .get(`${id}/Sensors`) + .then((response) => response.data.Members) + .catch((error) => console.log(error)); + if (!sensors) return; + const promises = sensors.map((sensor) => { + return api.get(sensor['@odata.id']).catch((error) => { + console.log(error); + return error; + }); + }); + return await api.all(promises).then( + api.spread((...responses) => { + const sensorData = responses.map(({ data }) => { + return { + name: data.Name, + status: data.Status.Health, + currentValue: data.Reading, + lowerCaution: data.Thresholds?.LowerCaution?.Reading, + upperCaution: data.Thresholds?.UpperCaution?.Reading, + lowerCritical: data.Thresholds?.LowerCritical?.Reading, + upperCritical: data.Thresholds?.UpperCritical?.Reading, + units: data.ReadingUnits, + }; + }); + commit('setSensors', sensorData); + }) + ); + }, + async getThermalSensors({ commit }, id) { + return await api + .get(`${id}/Thermal`) + .then(({ data: { Fans = [], Temperatures = [] } }) => { + const sensorData = []; + Fans.forEach((sensor) => { + sensorData.push({ + name: sensor.Name, + status: sensor.Status.Health, + currentValue: sensor.Reading, + lowerCaution: sensor.LowerThresholdNonCritical, + upperCaution: sensor.UpperThresholdNonCritical, + lowerCritical: sensor.LowerThresholdCritical, + upperCritical: sensor.UpperThresholdCritical, + units: sensor.ReadingUnits, + }); + }); + Temperatures.forEach((sensor) => { + sensorData.push({ + name: sensor.Name, + status: sensor.Status.Health, + currentValue: sensor.ReadingCelsius, + lowerCaution: sensor.LowerThresholdNonCritical, + upperCaution: sensor.UpperThresholdNonCritical, + lowerCritical: sensor.LowerThresholdCritical, + upperCritical: sensor.UpperThresholdCritical, + units: '℃', + }); + }); + commit('setSensors', sensorData); + }) + .catch((error) => console.log(error)); + }, + async getPowerSensors({ commit }, id) { + return await api + .get(`${id}/Power`) + .then(({ data: { Voltages = [] } }) => { + const sensorData = Voltages.map((sensor) => { + return { + name: sensor.Name, + status: sensor.Status.Health, + currentValue: sensor.ReadingVolts, + lowerCaution: sensor.LowerThresholdNonCritical, + upperCaution: sensor.UpperThresholdNonCritical, + lowerCritical: sensor.LowerThresholdCritical, + upperCritical: sensor.UpperThresholdCritical, + units: 'Volts', + }; + }); + commit('setSensors', sensorData); + }) + .catch((error) => console.log(error)); + }, + }, +}; + +export default SensorsStore; diff --git a/src/store/modules/HardwareStatus/ServerLedStore.js b/src/store/modules/HardwareStatus/ServerLedStore.js new file mode 100644 index 00000000..a8903e2a --- /dev/null +++ b/src/store/modules/HardwareStatus/ServerLedStore.js @@ -0,0 +1,55 @@ +import api from '@/store/api'; +import i18n from '@/i18n'; + +const ServerLedStore = { + namespaced: true, + state: { + indicatorLedActiveState: false, + }, + getters: { + getIndicatorLedActiveState: (state) => state.indicatorLedActiveState, + }, + mutations: { + setIndicatorLedActiveState(state, indicatorLedActiveState) { + state.indicatorLedActiveState = indicatorLedActiveState; + }, + }, + actions: { + async getIndicatorLedActiveState({ commit }) { + return await api + .get('/redfish/v1/Systems/system') + .then((response) => { + commit( + 'setIndicatorLedActiveState', + response.data.LocationIndicatorActive + ); + }) + .catch((error) => console.log(error)); + }, + async saveIndicatorLedActiveState({ commit }, payload) { + commit('setIndicatorLedActiveState', payload); + return await api + .patch('/redfish/v1/Systems/system', { + LocationIndicatorActive: payload, + }) + .then(() => { + if (payload) { + return i18n.t('pageServerLed.toast.successServerLedOn'); + } else { + return i18n.t('pageServerLed.toast.successServerLedOff'); + } + }) + .catch((error) => { + console.log(error); + commit('setIndicatorLedActiveState', !payload); + if (payload) { + throw new Error(i18n.t('pageServerLed.toast.errorServerLedOn')); + } else { + throw new Error(i18n.t('pageServerLed.toast.errorServerLedOff')); + } + }); + }, + }, +}; + +export default ServerLedStore; diff --git a/src/store/modules/HardwareStatus/SystemStore.js b/src/store/modules/HardwareStatus/SystemStore.js new file mode 100644 index 00000000..55f37542 --- /dev/null +++ b/src/store/modules/HardwareStatus/SystemStore.js @@ -0,0 +1,72 @@ +import api from '@/store/api'; +import i18n from '@/i18n'; + +const SystemStore = { + namespaced: true, + state: { + systems: [], + }, + getters: { + systems: (state) => state.systems, + }, + mutations: { + setSystemInfo: (state, data) => { + const system = {}; + system.assetTag = data.AssetTag; + system.description = data.Description; + system.firmwareVersion = data.BiosVersion; + system.hardwareType = data.Name; + system.health = data.Status.Health; + system.id = data.Id; + system.locationIndicatorActive = data.LocationIndicatorActive; + system.locationNumber = data.LocationNumber; + system.manufacturer = data.Manufacturer; + system.memorySummaryHealth = data.MemorySummary.Status.Health; + system.memorySummaryHealthRollup = data.MemorySummary.Status.HealthRollup; + system.memorySummaryState = data.MemorySummary.Status.State; + system.model = data.Model; + system.processorSummaryCount = data.ProcessorSummary.Count; + system.processorSummaryHealth = data.ProcessorSummary.Status.Health; + system.processorSummaryHealthRoll = + data.ProcessorSummary.Status.HealthRollup; + system.processorSummaryState = data.ProcessorSummary.Status.State; + system.powerState = data.PowerState; + system.serialNumber = data.SerialNumber; + system.healthRollup = data.Status.HealthRollup; + system.subModel = data.SubModel; + system.statusState = data.Status.State; + system.systemType = data.SystemType; + state.systems = [system]; + }, + }, + actions: { + async getSystem({ commit }) { + return await api + .get('/redfish/v1/Systems/system') + .then(({ data }) => commit('setSystemInfo', data)) + .catch((error) => console.log(error)); + }, + changeIdentifyLedState({ dispatch }, ledState) { + api + .patch('/redfish/v1/Systems/system', { + LocationIndicatorActive: ledState, + }) + .then(() => dispatch('getSystem')) + .catch((error) => { + dispatch('getSystem'); + console.log('error', error); + if (ledState) { + throw new Error( + i18n.t('pageHardwareStatus.toast.errorEnableIdentifyLed') + ); + } else { + throw new Error( + i18n.t('pageHardwareStatus.toast.errorDisableIdentifyLed') + ); + } + }); + }, + }, +}; + +export default SystemStore; -- cgit v1.2.3