Skip to content

Commit 208685f

Browse files
committed
Merge branch 'bugfix/fix-node-condition-display-bug' into q/2.8
2 parents 3f7ba7c + 99f7b81 commit 208685f

File tree

3 files changed

+111
-70
lines changed

3 files changed

+111
-70
lines changed

ui/src/ducks/app/nodes.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//@flow
12
import {
23
all,
34
call,

ui/src/ducks/reducer.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import { reducer as oidcReducer, UserState } from 'redux-oidc';
44

55
import config from './config';
66
import type { ConfigState } from './config';
7-
import nodes, { NodesState } from './app/nodes';
7+
import nodes from './app/nodes';
8+
import type { NodesState } from './app/nodes';
89
import pods from './app/pods';
910
import type { PodsState } from './app/pods';
1011
import volumes from './app/volumes';

ui/src/services/NodeUtils.js

Lines changed: 108 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//@flow
12
import { createSelector } from 'reselect';
23
import {
34
NODE_ALERTS_GROUP,
@@ -13,43 +14,77 @@ import {
1314
} from '../constants';
1415
import { compareHealth } from './utils';
1516
import type { IPInterfaces } from './salt/api';
17+
import type { RootState } from '../ducks/reducer';
18+
import type { NodesState } from '../ducks/app/nodes';
19+
import type { AlertsState } from '../ducks/app/alerts';
20+
import type { Brand } from '../services/api';
1621

1722
const METALK8S_CONTROL_PLANE_IP = 'metalk8s:control_plane_ip';
1823
const METALK8S_WORKLOAD_PLANE_IP = 'metalk8s:workload_plane_ip';
1924
const IP_INTERFACES = 'ip_interfaces';
2025

26+
// Note that: Reverse the selectors and result in order to type unknown number of selectors.
27+
export const createTypedSelector: <T>(
28+
selectorsResult: (...result: any) => T,
29+
...selectors: ((state: RootState) => any)[]
30+
) => T = (selectorsResult, ...selectors) =>
31+
createSelector(...selectors, selectorsResult);
32+
33+
type NodetableList = {
34+
name: { name: string, controlPlaneIP: string, workloadPlaneIP: string },
35+
status: {
36+
status: 'ready' | 'not_ready' | 'unknown',
37+
conditions: (
38+
| 'DiskPressure'
39+
| 'MemoryPressure'
40+
| 'PIDPressure'
41+
| 'NetworkUnavailable'
42+
| 'Unschedulable'
43+
)[],
44+
statusTextColor: string,
45+
computedStatus: [],
46+
},
47+
health: {
48+
health: 'health' | 'warning' | 'critical' | 'none',
49+
totalAlertsCounter: number,
50+
criticalAlertsCounter: number,
51+
warningAlertsCounter: number,
52+
},
53+
roles: string,
54+
}[];
55+
2156
const IPsInfoSelector = (state) => state.app.nodes.IPsInfo;
2257
const nodesSelector = (state) => state.app.nodes.list;
2358
const brandSelector = (state) => state.config.theme.brand;
2459
const alertsSelector = (state) => state.app.alerts.list;
2560

2661
// Return the data used by the Node list table
27-
export const getNodeListData = createSelector(
28-
nodesSelector,
29-
IPsInfoSelector,
30-
brandSelector,
31-
alertsSelector,
32-
(nodes, nodeIPsInfo, brand, alerts) => {
62+
export const getNodeListData = createTypedSelector<NodetableList>(
63+
(
64+
nodes: $PropertyType<NodesState, 'list'>,
65+
nodeIPsInfo: NodesState,
66+
brand: Brand,
67+
alerts: $PropertyType<AlertsState, 'list'>,
68+
) => {
3369
const mapped =
34-
nodes?.map((node) => {
35-
const IPsInfo = nodeIPsInfo?.[node.name];
70+
nodes.map((node) => {
71+
const conditions = node.conditions;
72+
const IPsInfo = nodeIPsInfo[node.name];
3673
let statusTextColor, health;
37-
const alertsNode = alerts?.filter(
74+
const alertsNode = alerts.filter(
3875
(alert) =>
39-
NODE_ALERTS_GROUP.includes(alert?.labels?.alertname) &&
76+
NODE_ALERTS_GROUP.includes(alert.labels.alertname) &&
4077
`${node.internalIP}:${PORT_NODE_EXPORTER}` ===
4178
alert.labels.instance,
4279
);
4380

44-
const totalAlertsCounter = alertsNode?.length ?? -1;
45-
const criticalAlertsCounter =
46-
alertsNode?.filter(
47-
(alert) => alert.labels.severity === STATUS_CRITICAL,
48-
)?.length ?? -1;
49-
const warningAlertsCounter =
50-
alertsNode?.filter(
51-
(alert) => alert.labels.severity === STATUS_WARNING,
52-
)?.length ?? -1;
81+
const totalAlertsCounter = alertsNode.length;
82+
const criticalAlertsCounter = alertsNode.filter(
83+
(alert) => alert.labels.severity === STATUS_CRITICAL,
84+
).length;
85+
const warningAlertsCounter = alertsNode.filter(
86+
(alert) => alert.labels.severity === STATUS_WARNING,
87+
).length;
5388

5489
if (criticalAlertsCounter > 0) {
5590
health = STATUS_CRITICAL;
@@ -64,86 +99,88 @@ export const getNodeListData = createSelector(
6499
}
65100

66101
const computedStatus = [];
67-
// The rules of the color of the node status
68-
// "green" when status.conditions['Ready'] == True and all other conditions are false
69-
// "yellow" when status.conditions['Ready'] == True and some other conditions are true
70-
// "red" when status.conditions['Ready'] == False
71-
// "grey" when there is no status.conditions
72-
if (
73-
node?.status === API_STATUS_READY &&
74-
node?.conditions.length === 0
75-
) {
76-
statusTextColor = brand?.healthy;
102+
/* The rules of the color of the node status
103+
<green> when status.conditions['Ready'] == True and all other conditions are false
104+
<yellow> when status.conditions['Ready'] == True and some other conditions are true
105+
<red> when status.conditions['Ready'] == False
106+
<grey> when there is no status.conditions */
107+
if (node.status === API_STATUS_READY && conditions.length === 0) {
108+
statusTextColor = brand.healthy;
77109
computedStatus.push(API_STATUS_READY);
78110
} else if (
79-
node?.status === API_STATUS_READY &&
80-
node?.conditions.length !== 0
111+
node.status === API_STATUS_READY &&
112+
conditions.length !== 0
81113
) {
82-
statusTextColor = brand?.warning;
83-
nodes.conditions.map((cond) => {
114+
statusTextColor = brand.warning;
115+
conditions.map((cond) => {
84116
return computedStatus.push(cond);
85117
});
86118
} else if (node.deploying && node.status === API_STATUS_UNKNOWN) {
87-
statusTextColor = brand?.textSecondary;
119+
statusTextColor = brand.textSecondary;
88120
computedStatus.push(API_STATUS_DEPLOYING);
89121
health = STATUS_NONE;
90-
} else if (node?.status !== API_STATUS_READY) {
91-
statusTextColor = brand?.critical;
122+
} else if (node.status !== API_STATUS_READY) {
123+
statusTextColor = brand.critical;
92124
computedStatus.push(API_STATUS_NOT_READY);
93125
health = STATUS_NONE;
94126
} else {
95-
statusTextColor = brand?.textSecondary;
127+
statusTextColor = brand.textSecondary;
96128
computedStatus.push(API_STATUS_UNKNOWN);
97129
health = STATUS_NONE;
98130
}
99131

100132
return {
101133
// According to the design, the IPs of Control Plane and Workload Plane are in the same Cell with Name
102134
name: {
103-
name: node?.name,
135+
name: node.name,
104136
controlPlaneIP: IPsInfo?.controlPlane?.ip,
105137
workloadPlaneIP: IPsInfo?.workloadPlane?.ip,
106138
},
107139
status: {
108-
status: node?.status,
109-
conditions: node?.conditions,
140+
status: node.status,
141+
conditions: node.conditions,
110142
statusTextColor,
111143
computedStatus,
112144
},
113-
roles: node?.roles,
145+
roles: node.roles,
114146
health: {
115147
health,
116148
totalAlertsCounter,
117149
criticalAlertsCounter,
118150
warningAlertsCounter,
119151
},
120152
};
121-
}) ?? [];
153+
}) || [];
122154

123155
return mapped.sort((a, b) =>
124156
compareHealth(b.health.health, a.health.health),
125157
);
126158
},
159+
nodesSelector,
160+
IPsInfoSelector,
161+
brandSelector,
162+
alertsSelector,
127163
);
128164

129-
// This function returns the IP and interface of Control Plane and Workload Plane for each Node
130-
// Arguments:
131-
// ipsInterfacesObject =
132-
// {
133-
// ip_interface: {
134-
// eth1:['10.0.1.42', 'fe80::f816:3eff:fe25:5843'],
135-
// eth3:['10.100.0.2', 'fe80::f816:3eff:fe37:2f34']
136-
// },
137-
// metalk8s:control_plane_ip: "10.0.1.42",
138-
// metalk8s:workload_plane_ip: "10.100.0.2"
139-
// }
140-
// Return
141-
// {
142-
// controlPlane: { ip: '10.0.1.42', interface: 'eth1'}
143-
// workloadPlane: { ip: '10.100.0.2', interface: 'eth3'},
144-
// }
165+
/*
166+
This function returns the IP and interface of Control Plane and Workload Plane for each Node
167+
Arguments:
168+
ipsInterfacesObject = {
169+
ip_interface: {
170+
eth1:['10.0.1.42', 'fe80::f816:3eff:fe25:5843'],
171+
eth3:['10.100.0.2', 'fe80::f816:3eff:fe37:2f34']
172+
},
173+
metalk8s:control_plane_ip: "10.0.1.42",
174+
metalk8s:workload_plane_ip: "10.100.0.2"
175+
}
176+
Return
177+
{
178+
controlPlane: { ip: '10.0.1.42', interface: 'eth1'}
179+
workloadPlane: { ip: '10.100.0.2', interface: 'eth3'},
180+
}
181+
*/
145182
export const nodesCPWPIPsInterface = (
146-
IPsInterfacesObject: IPInterfaces | boolean,
183+
IPsInterfacesObject: IPInterfaces | false,
147184
): {
148185
controlPlane: { ip: string, interface: string },
149186
workloadPlane: { ip: string, interface: string },
@@ -158,19 +195,21 @@ export const nodesCPWPIPsInterface = (
158195
return {
159196
controlPlane: {
160197
ip: IPsInterfacesObject[METALK8S_CONTROL_PLANE_IP],
161-
interface: Object.keys(IPsInterfacesObject[IP_INTERFACES]).find((en) =>
162-
IPsInterfacesObject[IP_INTERFACES][en].includes(
163-
IPsInterfacesObject[METALK8S_CONTROL_PLANE_IP],
164-
),
165-
),
198+
interface:
199+
Object.keys(IPsInterfacesObject[IP_INTERFACES]).find((en) =>
200+
IPsInterfacesObject[IP_INTERFACES][en].includes(
201+
IPsInterfacesObject[METALK8S_CONTROL_PLANE_IP],
202+
),
203+
) || '',
166204
},
167205
workloadPlane: {
168206
ip: IPsInterfacesObject[METALK8S_WORKLOAD_PLANE_IP],
169-
interface: Object.keys(IPsInterfacesObject[IP_INTERFACES]).find((en) =>
170-
IPsInterfacesObject[IP_INTERFACES][en].includes(
171-
IPsInterfacesObject[METALK8S_WORKLOAD_PLANE_IP],
172-
),
173-
),
207+
interface:
208+
Object.keys(IPsInterfacesObject[IP_INTERFACES]).find((en) =>
209+
IPsInterfacesObject[IP_INTERFACES][en].includes(
210+
IPsInterfacesObject[METALK8S_WORKLOAD_PLANE_IP],
211+
),
212+
) || '',
174213
},
175214
};
176215
};

0 commit comments

Comments
 (0)