From 1210b60095d478f3b1fb91a7b7dcbb288f5a24c1 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste WATENBERG Date: Tue, 31 Aug 2021 17:50:56 +0200 Subject: [PATCH 1/4] ui: Filter volume list per nodes in volume tabs on node details page --- ui/src/components/NodePageVolumesTab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/components/NodePageVolumesTab.js b/ui/src/components/NodePageVolumesTab.js index 30fa144de3..dcd3ecbb01 100644 --- a/ui/src/components/NodePageVolumesTab.js +++ b/ui/src/components/NodePageVolumesTab.js @@ -38,7 +38,7 @@ const NodePageVolumesTab = (props) => { const { name } = useParams(); const dispatch = useDispatch(); - const volumeListData = useVolumesWithAlerts(); + const volumeListData = useVolumesWithAlerts(name); useRefreshEffect(refreshVolumesAction, stopRefreshVolumesAction); useRefreshEffect( From 160e1a991dbcca6dff32c05387eb77ed1c5541be Mon Sep 17 00:00:00 2001 From: Jean-Baptiste WATENBERG Date: Thu, 2 Sep 2021 10:25:53 +0200 Subject: [PATCH 2/4] ui: Fix node alert filter and status --- ui/src/containers/NodePageRSP.js | 7 +- ui/src/services/NodeUtils.js | 122 +++++++++++++++++-------------- 2 files changed, 72 insertions(+), 57 deletions(-) diff --git a/ui/src/containers/NodePageRSP.js b/ui/src/containers/NodePageRSP.js index 15d452df4f..5101e7f33b 100644 --- a/ui/src/containers/NodePageRSP.js +++ b/ui/src/containers/NodePageRSP.js @@ -123,10 +123,13 @@ const NodePageRSP = (props) => { const alertList = useAlerts({ alertname: NODE_ALERTS_GROUP, - instance: `${instanceIP}:${PORT_NODE_EXPORTER}`, }); - const alertsNode = (alertList && alertList.alerts) || []; + const alertsNode = ((alertList && alertList.alerts) || []).filter( + (alert) => + alert.labels.instance === `${instanceIP}:${PORT_NODE_EXPORTER}` || + alert.labels.node === name, + ); const isHealthTabActive = location.pathname.endsWith('/overview'); const isAlertsTabActive = location.pathname.endsWith('/alerts'); diff --git a/ui/src/services/NodeUtils.js b/ui/src/services/NodeUtils.js index bb7f8ebe20..cf219bb8bb 100644 --- a/ui/src/services/NodeUtils.js +++ b/ui/src/services/NodeUtils.js @@ -10,13 +10,18 @@ import { API_STATUS_NOT_READY, API_STATUS_UNKNOWN, API_STATUS_DEPLOYING, + STATUS_HEALTH, } from '../constants'; import { compareHealth } from './utils'; import type { IPInterfaces } from './salt/api'; import type { RootState } from '../ducks/reducer'; import type { NodesState } from '../ducks/app/nodes'; import type { Brand } from '../services/api'; -import { getHealthStatus, filterAlerts, type Alert } from '../services/alertUtils'; +import { + getHealthStatus, + filterAlerts, + type Alert, +} from '../services/alertUtils'; const METALK8S_CONTROL_PLANE_IP = 'metalk8s:control_plane_ip'; const METALK8S_WORKLOAD_PLANE_IP = 'metalk8s:workload_plane_ip'; @@ -56,33 +61,35 @@ const IPsInfoSelector = (state) => state.app.nodes.IPsInfo; const nodesSelector = (state) => state.app.nodes.list; // Return the data used by the Node list table -export const getNodeListData = (alerts: Array, brand: Brand) => createTypedSelector( - ( - nodes: $PropertyType, - nodeIPsInfo: NodesState - ) => { - const mapped = - nodes.map((node) => { - const conditions = node.conditions; - const IPsInfo = nodeIPsInfo[node.name]; - let statusTextColor, health; +export const getNodeListData = (alerts: Array, brand: Brand) => + createTypedSelector( + (nodes: $PropertyType, nodeIPsInfo: NodesState) => { + const mapped = + nodes.map((node) => { + const conditions = node.conditions; + const IPsInfo = nodeIPsInfo[node.name]; + let statusTextColor, health; - const alertsNode = filterAlerts(alerts, { - alertname: NODE_ALERTS_GROUP, - instance: `${node.internalIP}:${PORT_NODE_EXPORTER}`, - }); + const alertsNode = filterAlerts(alerts, { + alertname: NODE_ALERTS_GROUP, + }).filter( + (alert) => + alert.labels.instance === + `${node.internalIP}:${PORT_NODE_EXPORTER}` || + alert.labels.node === node.name, + ); - const totalAlertsCounter = alertsNode.length; - const criticalAlertsCounter = alertsNode.filter( - (alert) => alert.labels.severity === STATUS_CRITICAL, - ).length; - const warningAlertsCounter = alertsNode.filter( - (alert) => alert.labels.severity === STATUS_WARNING, - ).length; + const totalAlertsCounter = alertsNode.length; + const criticalAlertsCounter = alertsNode.filter( + (alert) => alert.labels.severity === STATUS_CRITICAL, + ).length; + const warningAlertsCounter = alertsNode.filter( + (alert) => alert.labels.severity === STATUS_WARNING, + ).length; - health = getHealthStatus(alertsNode); - const computedStatus = []; - /* The rules of the color of the node status + health = getHealthStatus(alertsNode); + const computedStatus = []; + /* The rules of the color of the node status when status.conditions['Ready'] == True and all other conditions are false when status.conditions['Ready'] == True and some other conditions are true when status.conditions['Ready'] == False @@ -105,43 +112,48 @@ export const getNodeListData = (alerts: Array, brand: Brand) => createTyp } else if (node.status !== API_STATUS_READY) { statusTextColor = brand.statusCritical; computedStatus.push(API_STATUS_NOT_READY); - health = STATUS_NONE; + //If no alert is raised on the node but kubernetes + //report a non-ready node we set the node health to NONE + //else we set it to the highest alert status raised on the node. + if (health === STATUS_HEALTH) { + health = STATUS_NONE; + } } else { statusTextColor = brand.textSecondary; computedStatus.push(API_STATUS_UNKNOWN); health = STATUS_NONE; } - return { - // According to the design, the IPs of Control Plane and Workload Plane are in the same Cell with Name - name: { - name: node.name, - controlPlaneIP: IPsInfo?.controlPlane?.ip, - workloadPlaneIP: IPsInfo?.workloadPlane?.ip, - }, - status: { - status: node.status, - conditions: node.conditions, - statusTextColor, - computedStatus, - }, - roles: node.roles, - health: { - health, - totalAlertsCounter, - criticalAlertsCounter, - warningAlertsCounter, - }, - }; - }) || []; + return { + // According to the design, the IPs of Control Plane and Workload Plane are in the same Cell with Name + name: { + name: node.name, + controlPlaneIP: IPsInfo?.controlPlane?.ip, + workloadPlaneIP: IPsInfo?.workloadPlane?.ip, + }, + status: { + status: node.status, + conditions: node.conditions, + statusTextColor, + computedStatus, + }, + roles: node.roles, + health: { + health, + totalAlertsCounter, + criticalAlertsCounter, + warningAlertsCounter, + }, + }; + }) || []; - return mapped.sort((a, b) => - compareHealth(b.health.health, a.health.health), - ); - }, - nodesSelector, - IPsInfoSelector, -); + return mapped.sort((a, b) => + compareHealth(b.health.health, a.health.health), + ); + }, + nodesSelector, + IPsInfoSelector, + ); /* This function returns the IP and interface of Control Plane and Workload Plane for each Node From 3c9589c948a636570e35907e8eb77d393b0a8221 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste WATENBERG Date: Thu, 2 Sep 2021 10:58:44 +0200 Subject: [PATCH 3/4] ui: Hide deploy button when a node is unavailable but already deployed --- ui/src/components/NodePageOverviewTab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/src/components/NodePageOverviewTab.js b/ui/src/components/NodePageOverviewTab.js index 731859f758..1c57b4ddb4 100644 --- a/ui/src/components/NodePageOverviewTab.js +++ b/ui/src/components/NodePageOverviewTab.js @@ -195,7 +195,7 @@ const NodePageOverviewTab = (props) => { {name} - {currentNodeReturnByK8S?.status === API_STATUS_UNKNOWN ? ( + {currentNodeReturnByK8S?.status === API_STATUS_UNKNOWN && !currentNodeReturnByK8S.internalIP ? ( !currentNodeReturnByK8S?.deploying ? ( Date: Thu, 2 Sep 2021 11:08:01 +0200 Subject: [PATCH 4/4] changelog: Mention UI mutli nodes fixes --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9dceb9a840..7b0c82b8f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ - Bump Kubernetes version to 1.21.4 (PR[#3495](https://github.com/scality/metalk8s/pull/3495)) +- Fix UI issues in multi nodes environment when a node + is unavailable (PR[#3521](https://github.com/scality/metalk8s/pull/3521)) + ## Release 2.10.2 ### Bug fixes - Fix the link to documentation from the UI navigation bar