diff options
author | Dixsie Wolmers <dixsie@ibm.com> | 2020-01-23 04:47:56 +0300 |
---|---|---|
committer | Yoshie Muranaka <yoshiemuranaka@gmail.com> | 2020-01-29 01:18:05 +0300 |
commit | f65ee346bedb1811e88b12542abce0d18bb5fc32 (patch) | |
tree | 04b0a5cc2096a48b9c2b15dc571a1db680802c89 /src | |
parent | dc04feb5596a85619e98d2d594b065e92c8b8fa4 (diff) | |
download | webui-vue-f65ee346bedb1811e88b12542abce0d18bb5fc32.tar.xz |
Add store modules needed to support overview view
- Update overview page to get data from store
Signed-off-by: Dixsie Wolmers <dixsie@ibm.com>
Signed-off-by: Derick Montague <derick.montague@ibm.com>
Change-Id: Id2fcad660efc0da5c7b878e872355bf5773c7ed7
Diffstat (limited to 'src')
-rw-r--r-- | src/store/index.js | 14 | ||||
-rw-r--r-- | src/store/modules/Configuration/FirmwareStore.js | 60 | ||||
-rw-r--r-- | src/store/modules/Configuration/NetworkSettingsStore.js | 48 | ||||
-rw-r--r-- | src/store/modules/Control/PowerCapStore.js | 36 | ||||
-rw-r--r-- | src/store/modules/Control/PowerConsumptionStore.js | 35 | ||||
-rw-r--r-- | src/store/modules/GlobalStore.js | 30 | ||||
-rw-r--r-- | src/store/modules/Health/EventLogStore.js | 72 | ||||
-rw-r--r-- | src/store/modules/Overview/OverviewStore.js | 48 | ||||
-rw-r--r-- | src/views/Overview/Overview.vue | 118 | ||||
-rw-r--r-- | src/views/Overview/OverviewEvents.vue | 60 | ||||
-rw-r--r-- | src/views/Overview/OverviewQuickLinks.vue | 37 |
11 files changed, 428 insertions, 130 deletions
diff --git a/src/store/index.js b/src/store/index.js index 889e52b4..cb63e545 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -4,6 +4,12 @@ import Vuex from 'vuex'; import GlobalStore from './modules/GlobalStore'; import AuthenticationStore from './modules/Authentication/AuthenticanStore'; import LocalUserManagementStore from './modules/AccessControl/LocalUserMangementStore'; +import OverviewStore from './modules/Overview/OverviewStore'; +import FirmwareStore from './modules/Configuration/FirmwareStore'; +import PowerConsumptionStore from './modules/Control/PowerConsumptionStore'; +import PowerCapStore from './modules/Control/PowerCapStore'; +import NetworkSettingStore from './modules/Configuration/NetworkSettingsStore'; +import EventLogStore from './modules/Health/EventLogStore'; import WebSocketPlugin from './plugins/WebSocketPlugin'; @@ -16,7 +22,13 @@ export default new Vuex.Store({ modules: { global: GlobalStore, authentication: AuthenticationStore, - localUsers: LocalUserManagementStore + localUsers: LocalUserManagementStore, + overview: OverviewStore, + firmware: FirmwareStore, + powerConsumption: PowerConsumptionStore, + powerCap: PowerCapStore, + networkSettings: NetworkSettingStore, + eventLog: EventLogStore }, plugins: [WebSocketPlugin] }); diff --git a/src/store/modules/Configuration/FirmwareStore.js b/src/store/modules/Configuration/FirmwareStore.js new file mode 100644 index 00000000..5185a138 --- /dev/null +++ b/src/store/modules/Configuration/FirmwareStore.js @@ -0,0 +1,60 @@ +import api from '../../api'; + +const FirmwareStore = { + namespaced: true, + state: { + firmwareInfo: null, + bmcActiveVersion: '--', + hostActiveVersion: '--' + }, + getters: { + firmwareInfo: state => state.firmwareInfo, + bmcActiveVersion: state => state.bmcActiveVersion, + hostActiveVersion: state => state.hostActiveVersion + }, + mutations: { + setFirmwareInfo: (state, firmwareInfo) => + (state.firmwareInfo = firmwareInfo), + setBmcActiveVersion: (state, bmcActiveVersion) => + (state.bmcActiveVersion = bmcActiveVersion), + setHostActiveVersion: (state, hostActiveVersion) => + (state.hostActiveVersion = hostActiveVersion) + }, + actions: { + getFirmwareInfo({ commit }) { + api + .get('/xyz/openbmc_project/software/enumerate') + .then(response => { + const firmwareInfo = response.data.data; + const functionalImages = + firmwareInfo['/xyz/openbmc_project/software/functional'].endpoints; + for (let key in firmwareInfo) { + /** + * If "Functional" activation status is + * functional, else it is "activation" + * github.com/openbmc/phosphor-dbus-interfaces/blob/master/xyz/openbmc_project/Software/Activation.interface.yaml + */ + if (firmwareInfo[key].hasOwnProperty('Version')) { + let activationStatus = ''; + const imageType = firmwareInfo[key].Purpose.split('.').pop(); + if (functionalImages.includes(key)) { + activationStatus = 'Functional'; + } + // Get BMC and Host active Versions + if (activationStatus == 'Functional' && imageType == 'BMC') { + commit('setBmcActiveVersion', firmwareInfo[key].Version); + } + if (activationStatus == 'Functional' && imageType == 'Host') { + commit('setHostActiveVersion', firmwareInfo[key].Version); + } + } + } + }) + .catch(error => { + console.log(error); + }); + } + } +}; + +export default FirmwareStore; diff --git a/src/store/modules/Configuration/NetworkSettingsStore.js b/src/store/modules/Configuration/NetworkSettingsStore.js new file mode 100644 index 00000000..ee58a77b --- /dev/null +++ b/src/store/modules/Configuration/NetworkSettingsStore.js @@ -0,0 +1,48 @@ +import api from '../../api'; + +const NetworkSettingsStore = { + namespaced: true, + state: { + networkData: null, + ipAddress: '--', + macAddress: '--' + }, + getters: { + networkData: state => state.networkData, + ipAddress: state => state.ipAddress, + macAddress: state => state.macAddress + }, + mutations: { + setNetworkData: (state, networkData) => (state.networkData = networkData), + setIpAddress: (state, ipAddress) => (state.ipAddress = ipAddress), + setMacAddress: (state, macAddress) => (state.macAddress = macAddress) + }, + actions: { + getNetworkData({ commit }) { + api + .get('/xyz/openbmc_project/network/enumerate') + .then(response => { + const networkData = response.data.data; + const ipAddresses = []; + const interfaceId = /eth[0-9]/; + for (let key in networkData) { + if (key.includes('ipv4')) { + ipAddresses.push(networkData[key].Address); + } + if ( + key.match(interfaceId) && + networkData[key].MACAddress !== undefined + ) { + commit('setMacAddress', networkData[key].MACAddress); + } + } + commit('setIpAddress', ipAddresses); + }) + .catch(error => { + console.log('Network Data:', error); + }); + } + } +}; + +export default NetworkSettingsStore; diff --git a/src/store/modules/Control/PowerCapStore.js b/src/store/modules/Control/PowerCapStore.js new file mode 100644 index 00000000..bef9f47b --- /dev/null +++ b/src/store/modules/Control/PowerCapStore.js @@ -0,0 +1,36 @@ +import api from '../../api'; + +const PowerCapStore = { + namespaced: true, + state: { + powerCapData: null, + powerCapValue: 'Not enabled' + }, + getters: { + powerCapData: state => state.powerCapData, + powerCapValue: state => state.powerCapValue + }, + mutations: { + setPowerCapData: (state, powerCapData) => + (state.powerCapData = powerCapData), + setPowerCapValue: (state, powerCapValue) => + (state.powerCapValue = powerCapValue) + }, + actions: { + getPowerCapData({ commit }) { + api + .get('/xyz/openbmc_project/control/host0/power_cap') + .then(response => { + const powerCapData = response.data.data; + if (powerCapData.PowerCapEnable) { + commit('setPowerCapValue', powerCapData.PowerCap + ' W'); + } + }) + .catch(error => { + console.log('Power cap error', error); + }); + } + } +}; + +export default PowerCapStore; diff --git a/src/store/modules/Control/PowerConsumptionStore.js b/src/store/modules/Control/PowerConsumptionStore.js new file mode 100644 index 00000000..03ccffce --- /dev/null +++ b/src/store/modules/Control/PowerConsumptionStore.js @@ -0,0 +1,35 @@ +import api from '../../api'; + +const PowerConsumptionStore = { + namespaced: true, + state: { + powerData: null, + powerConsumption: 'Not available' + }, + getters: { + powerData: state => state.powerData, + powerConsumption: state => state.powerConsumption + }, + mutations: { + setPowerData: (state, powerData) => (state.powerData = powerData), + setPowerConsumption: (state, powerConsumption) => + (state.powerConsumption = powerConsumption) + }, + actions: { + getPowerData({ commit }) { + api + .get('/xyz/openbmc_project/sensors/power/total_power') + .then(response => { + const powerData = response.data.data; + let powerConsumption = + powerData.Value * Math.pow(10, powerData.Scale) + ' W'; + commit('setPowerConsumption', powerConsumption); + }) + .catch(error => { + console.log('Power Consumption', error); + }); + } + } +}; + +export default PowerConsumptionStore; diff --git a/src/store/modules/GlobalStore.js b/src/store/modules/GlobalStore.js index 80d9c1a3..18d5043d 100644 --- a/src/store/modules/GlobalStore.js +++ b/src/store/modules/GlobalStore.js @@ -25,23 +25,19 @@ const GlobalStore = { namespaced: true, state: { hostName: '--', + bmcTime: null, hostStatus: 'unreachable' }, getters: { - hostName(state) { - return state.hostName; - }, - hostStatus(state) { - return state.hostStatus; - } + hostName: state => state.hostName, + hostStatus: state => state.hostStatus, + bmcTime: state => state.bmcTime }, mutations: { - setHostName(state, hostName) { - state.hostName = hostName; - }, - setHostStatus(state, hostState) { - state.hostStatus = hostStateMapper(hostState); - } + setHostName: (state, hostName) => (state.hostName = hostName), + setBmcTime: (state, bmcTime) => (state.bmcTime = bmcTime), + setHostStatus: (state, hostState) => + (state.hostState = hostStateMapper(hostState)) }, actions: { getHostName({ commit }) { @@ -53,6 +49,16 @@ const GlobalStore = { }) .catch(error => console.log(error)); }, + getBmcTime({ commit }) { + api + .get('/xyz/openbmc_project/time/bmc') + .then(response => { + // bmcTime is stored in microseconds, convert to millseconds + const bmcTime = response.data.data.Elapsed / 1000; + commit('setBmcTime', bmcTime); + }) + .catch(error => console.log(error)); + }, getHostStatus({ commit }) { api .get('/xyz/openbmc_project/state/host0/attr/CurrentHostState') diff --git a/src/store/modules/Health/EventLogStore.js b/src/store/modules/Health/EventLogStore.js new file mode 100644 index 00000000..404a9639 --- /dev/null +++ b/src/store/modules/Health/EventLogStore.js @@ -0,0 +1,72 @@ +import api from '../../api'; + +const severityToPriorityMap = { + Emergency: 'High', + Alert: 'High', + Critical: 'High', + Error: 'High', + Warning: 'Medium', + Notice: 'Low', + Debug: 'Low', + Informational: 'Low' +}; + +const EventLogStore = { + namespaced: true, + state: { + eventLogData: null + }, + getters: { + eventLogData: state => state.eventLogData + }, + mutations: { + setEventLogData: (state, eventLogData) => + (state.eventLogData = eventLogData) + }, + actions: { + getEventLogData({ commit }) { + api + .get('/xyz/openbmc_project/logging/enumerate') + .then(response => { + const eventLog = response.data.data; + const entryNumber = /[1-9]/; + const eventLogEntries = []; + /** + * Entry log endpoints: + * 'entry' + entry id contain event log entry information + * 'callout' contains part number and serial number for part affected + */ + for (let key in eventLog) { + // Check for event log entry: + if ( + key.includes('entry') && + key.match(entryNumber) && + !key.includes('callout') + ) { + const eventKey = eventLog[key]; + const eventSeverity = eventKey.Severity.split('.').pop(); + const eventPriority = severityToPriorityMap[eventSeverity]; + eventLogEntries.push( + Object.assign( + { + logId: eventKey.Id, + priority: eventPriority, + timestamp: eventKey.Timestamp, + eventID: eventKey.EventID, + description: eventKey.Description + }, + eventKey + ) + ); + commit('setEventLogData', eventLogEntries); + } + } + }) + .catch(error => { + console.log('Event Log Data:', error); + }); + } + } +}; + +export default EventLogStore; diff --git a/src/store/modules/Overview/OverviewStore.js b/src/store/modules/Overview/OverviewStore.js new file mode 100644 index 00000000..8d0613ad --- /dev/null +++ b/src/store/modules/Overview/OverviewStore.js @@ -0,0 +1,48 @@ +import api from '../../api'; + +const OverviewStore = { + namespaced: true, + state: { + serverInfo: null, + serverModel: '--', + serverManufacturer: '--', + serverSerialNumber: '--' + }, + getters: { + serverInfo: state => state.serverInfo, + serverModel: state => state.serverModel, + serverManufacturer: state => state.serverManufacturer, + serverSerialNumber: state => state.serverSerialNumber + }, + mutations: { + setServerInfo: (state, serverInfo) => (state.serverInfo = serverInfo), + setServerModel: (state, serverModel) => (state.serverModel = serverModel), + setServerManufacturer: (state, serverManufacturer) => + (state.serverManufacturer = serverManufacturer), + setServerSerialNumber: (state, serverSerialNumber) => + (state.serverSerialNumber = serverSerialNumber) + }, + actions: { + getServerInfo({ commit }) { + api + .get('/xyz/openbmc_project/inventory/system') + .then(response => { + const serverInfo = response.data.data; + if (serverInfo.Model) { + commit('setServerModel', serverInfo.Model); + } + if (serverInfo.SerialNumber) { + commit('setServerSerialNumber', serverInfo.SerialNumber); + } + if (serverInfo.Manufacturer) { + commit('setServerManufacturer', serverInfo.Manufacturer); + } + }) + .catch(error => { + console.log(error); + }); + } + } +}; + +export default OverviewStore; diff --git a/src/views/Overview/Overview.vue b/src/views/Overview/Overview.vue index bf3f27fb..570f8494 100644 --- a/src/views/Overview/Overview.vue +++ b/src/views/Overview/Overview.vue @@ -3,30 +3,30 @@ <PageTitle /> <b-row> <b-col lg="8" sm="12"> - <PageSection sectionTitle="Server Information"> + <PageSection sectionTitle="Server information"> <b-row> <b-col sm="6"> <dl> - <dt>MODEL</dt> - <dd>{{ system.Model || "N/A" }}</dd> + <dt>Model</dt> + <dd>{{ serverModel }}</dd> </dl> </b-col> <b-col sm="6"> <dl> - <dt>MANUFACTURER</dt> - <dd>{{ system.Manufacturer || "N/A" }}</dd> + <dt>Manufacturer</dt> + <dd>{{ serverManufacturer }}</dd> </dl> </b-col> <b-col sm="6"> <dl> - <dt>SERIAL NUMBER</dt> - <dd>{{ system.SerialNumber || "N/A" }}</dd> + <dt>Serial number</dt> + <dd>{{ serverSerialNumber }}</dd> </dl> </b-col> <b-col sm="6"> <dl> - <dt>FIRMWARE VERSION</dt> - <dd>{{ software.Version || "N/A" }}</dd> + <dt>Firmware version</dt> + <dd>{{ hostActiveVersion }}</dd> </dl> </b-col> </b-row> @@ -35,26 +35,26 @@ <b-row> <b-col sm="6"> <dl> - <dt>HOSTNAME</dt> - <dd>{{ network.config.HostName || "N/A" }}</dd> + <dt>Hostname</dt> + <dd>{{ hostName }}</dd> </dl> </b-col> <b-col sm="6"> <dl> - <dt>MAC ADDRESS</dt> - <dd>{{ network.eth0.MACAddress || "N/A" }}</dd> + <dt>MAC address</dt> + <dd>{{ macAddress }}</dd> </dl> </b-col> <b-col sm="6"> <dl> - <dt>IP ADDRESS</dt> - <dd>{{ network.ipv4.Address || "N/A" }}</dd> + <dt>IP address</dt> + <dd v-for="ip in ipAddress" v-bind:key="ip.id">{{ ip }}</dd> </dl> </b-col> <b-col sm="6"> <dl> - <dt>FIRMWARE VERSION</dt> - <dd>{{ logging.entry.Version || "N/A" }}</dd> + <dt>Firmware version</dt> + <dd>{{ bmcActiveVersion }}</dd> </dl> </b-col> </b-row> @@ -63,26 +63,25 @@ <b-row> <b-col sm="6"> <dl> - <dt>POWER CONSUMPTION</dt> - <dd>{{ total_power.description || "N/A" }}</dd> + <dt>Power consumption</dt> + <dd>{{ powerConsumption }}</dd> </dl> </b-col> <b-col sm="6"> <dl> - <dt>POWER CAP</dt> - <dd v-if="!power_cap.PowerCapEnable">Not enabled</dd> - <dd v-else>{{ power_cap.PowerCap }}</dd> + <dt>Power cap</dt> + <dd>{{ powerCapValue }}</dd> </dl> </b-col> </b-row> </PageSection> </b-col> <b-col lg="4" sm="12"> - <quickLinks /> + <OverviewQuickLinks /> </b-col> </b-row> <PageSection sectionTitle="High priority events"> - <events /> + <OverviewEvents /> </PageSection> </b-container> </template> @@ -92,56 +91,39 @@ import OverviewQuickLinks from "./OverviewQuickLinks"; import OverviewEvents from "./OverviewEvents"; import PageTitle from "../../components/Global/PageTitle"; import PageSection from "../../components/Global/PageSection"; - +import { mapState } from "vuex"; export default { name: "Overview", components: { - quickLinks: OverviewQuickLinks, - events: OverviewEvents, + OverviewQuickLinks, + OverviewEvents, PageTitle, PageSection }, - data() { - return { - logging: { - entry: { - Description: - "An internal failure has occurred while performing an operation.", - EventID: "ABCDEF123", - Id: 1, - Resolved: false, - Severity: "CRITICAL", - Timestamp: 1574782085071, - Version: "openbmc-v1.0.0" - } - }, - network: { - config: { - HostName: "Name of the Host" - }, - eth0: { - MACAddress: "00:00:00:00:00:00" - }, - ipv4: { - Address: "00.00.00.00" - } - }, - power_cap: { - PowerCap: 0, - PowerCapEnable: false - }, - software: { - Version: "OPENBMC-v1" - }, - system: { - Manufacturer: "", - Model: "0000000000000000", - SerialNumber: "0000000000000000" - }, - total_power: { - description: "0" - } - }; + created() { + this.getOverviewInfo(); + }, + computed: mapState({ + serverModel: state => state.overview.serverModel, + serverManufacturer: state => state.overview.serverManufacturer, + serverSerialNumber: state => state.overview.serverSerialNumber, + hostName: state => state.global.hostName, + hostActiveVersion: state => state.firmware.hostActiveVersion, + bmcActiveVersion: state => state.firmware.bmcActiveVersion, + powerConsumption: state => state.powerConsumption.powerConsumption, + powerCapValue: state => state.powerCap.powerCapValue, + ipAddress: state => state.networkSettings.ipAddress, + macAddress: state => state.networkSettings.macAddress + }), + methods: { + getOverviewInfo() { + this.$store.dispatch("overview/getServerInfo"); + this.$store.dispatch("global/getHostName"); + this.$store.dispatch("firmware/getFirmwareInfo"); + this.$store.dispatch("powerConsumption/getPowerData"); + this.$store.dispatch("powerCap/getPowerCapData"); + this.$store.dispatch("networkSettings/getNetworkData"); + } } }; </script> diff --git a/src/views/Overview/OverviewEvents.vue b/src/views/Overview/OverviewEvents.vue index b49ed6e4..05106067 100644 --- a/src/views/Overview/OverviewEvents.vue +++ b/src/views/Overview/OverviewEvents.vue @@ -1,43 +1,43 @@ <template> - <b-list-group> - <b-list-group-item href="#" class="flex-column align-items-start"> - #{{ logging.entry.Id }} - <b-badge variant="danger">{{ logging.entry.Severity }}</b-badge> - <div class="d-flex w-100 justify-content-between"> - <small>{{ - logging.entry.Timestamp | date("MMM, DD YYYY HH:MM:SS A ZZ") - }}</small> - <ChevronRight16 /> - </div> - <p class="mb-1"> - {{ logging.entry.EventID }}: {{ logging.entry.Description }} - </p> - </b-list-group-item> - </b-list-group> + <div> + <b-list-group v-for="logData in eventLogData" :key="logData.id"> + <b-list-group-item href="#" class="flex-column align-items-start"> + {{ "#" + logData.logId }} + <b-badge variant="danger">{{ logData.priority }}</b-badge> + <div class="d-flex w-100 justify-content-between"> + <small>{{ + logData.Timestamp | date("MMM DD YYYY HH:MM:SS A ZZ") + }}</small> + <ChevronRight16 /> + </div> + <p class="mb-1">{{ logData.eventID }}: {{ logData.description }}</p> + </b-list-group-item> + </b-list-group> + <b-list-group v-if="!eventLogData"> + There are no high priority events to display at this time. + </b-list-group> + </div> </template> <script> import ChevronRight16 from "@carbon/icons-vue/es/chevron--right/16"; - export default { name: "events", components: { ChevronRight16 }, - data() { - return { - logging: { - entry: { - Description: - "An internal failure has occurred while performing an operation.", - EventID: "ABCDEF123", - Id: 1, - Resolved: false, - Severity: "Error", - Timestamp: 1574782085071 - } - } - }; + created() { + this.getEventLogData(); + }, + computed: { + eventLogData() { + return this.$store.getters["eventLog/eventLogData"]; + } + }, + methods: { + getEventLogData() { + this.$store.dispatch("eventLog/getEventLogData"); + } } }; </script> diff --git a/src/views/Overview/OverviewQuickLinks.vue b/src/views/Overview/OverviewQuickLinks.vue index f8806b27..577ea5ff 100644 --- a/src/views/Overview/OverviewQuickLinks.vue +++ b/src/views/Overview/OverviewQuickLinks.vue @@ -1,22 +1,17 @@ <template> <b-list-group> - <b-list-group-item - href="#" - variant="danger" - v-show="logging.entry.Severity === 'Error'" - >View 1 high priority event</b-list-group-item - > + <!-- TODO: add event log priority events count --> <b-list-group-item> <dl> <dt>BMC time</dt> - <dd>{{ bmc.Elapsed | date("MMM, DD YYYY HH:MM:SS A ZZ") }}</dd> + <dd>{{ bmcTime | date("MMM, DD YYYY HH:MM:SS A ZZ") }}</dd> </dl> </b-list-group-item> <b-list-group-item> <!-- TODO: add toggle LED on/off funtionality --> - <b-form-checkbox v-model="checked" name="check-button" switch> + <b-form-checkbox v-model="serverLedChecked" name="check-button" switch> Turn - <span v-if="!checked">on</span> + <span v-if="!serverLedChecked">on</span> <span v-else>off</span> server LED </b-form-checkbox> </b-list-group-item> @@ -41,23 +36,27 @@ <script> import ChevronRight16 from "@carbon/icons-vue/es/chevron--right/16"; - export default { name: "quickLinks", components: { ChevronRight16 }, + created() { + this.getBmcTime(); + }, + computed: { + bmcTime() { + return this.$store.getters["global/bmcTime"]; + } + }, + methods: { + getBmcTime() { + this.$store.dispatch("global/getBmcTime"); + } + }, data() { return { - bmc: { - Elapsed: 1574782085071 - }, - logging: { - entry: { - Severity: "Error" - } - }, - checked: false + serverLedChecked: false }; } }; |