From fd4a553b46e7da8b2d1dfad33977af02ecd0cc16 Mon Sep 17 00:00:00 2001 From: Ivan Devat Date: Thu, 20 Oct 2022 14:05:02 +0200 Subject: [PATCH 1/5] expand cluster status flag set --- .../cluster/clusterStatus/apiToState/index.ts | 10 +++++---- .../cluster/clusterStatus/apiToState/nodes.ts | 21 +++++++++++++++---- .../reducers/cluster/clusterStatus/reducer.ts | 1 + .../reducers/cluster/clusterStatus/types.ts | 3 ++- src/app/view/cluster/acl/lists/AclLists.tsx | 2 +- .../constraints/ConstraintFilteredList.tsx | 2 +- .../fenceDevices/list/FenceDeviceList.tsx | 2 +- .../properties/ClusterPropertiesPage.tsx | 2 +- .../cluster/resources/tree/ResourceTree.tsx | 2 +- .../clusterList/DashboardClusterCellName.tsx | 5 +++-- src/app/view/share/ClusterStatusLabel.tsx | 6 ++++-- src/app/view/share/nvpair/NVPairListView.tsx | 2 +- .../useLauncherDisableClusterNotRunning.tsx | 2 +- 13 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/app/store/reducers/cluster/clusterStatus/apiToState/index.ts b/src/app/store/reducers/cluster/clusterStatus/apiToState/index.ts index e74e7bbc7..98c5c5310 100644 --- a/src/app/store/reducers/cluster/clusterStatus/apiToState/index.ts +++ b/src/app/store/reducers/cluster/clusterStatus/apiToState/index.ts @@ -16,13 +16,15 @@ export const apiToState = (apiClusterStatus: ApiCluster): Cluster => { fenceDevicesSeverity, resourceOnNodeStatusList, } = analyzeApiResources(apiClusterStatus.resource_list); - const { nodeList, nodesSeverity, clusterStatus } = processApiNodes( - apiClusterStatus.node_list, - apiClusterStatus.node_attr ?? {}, - ); + const { nodeList, nodesSeverity, clusterStatus, hasCibInfo } = + processApiNodes( + apiClusterStatus.node_list, + apiClusterStatus.node_attr ?? {}, + ); return { name: apiClusterStatus.cluster_name, status: clusterStatus, + hasCibInfo: hasCibInfo, nodeList, issueList: transformIssues(apiClusterStatus), resourceTree, diff --git a/src/app/store/reducers/cluster/clusterStatus/apiToState/nodes.ts b/src/app/store/reducers/cluster/clusterStatus/apiToState/nodes.ts index 2d0329978..935268393 100644 --- a/src/app/store/reducers/cluster/clusterStatus/apiToState/nodes.ts +++ b/src/app/store/reducers/cluster/clusterStatus/apiToState/nodes.ts @@ -98,14 +98,25 @@ const countNodesSeverity = (apiNodeList: ApiNode[]): StatusSeverity => { }; const getClusterStatus = (apiNodeList: ApiNode[]): Cluster["status"] => { - if (apiNodeList.every(n => n.status === "unknown")) { - return "unknown"; + if ( + apiNodeList.every(n => n.status === "online") + && apiNodeList.some(n => "quorum" in n && n.quorum) + ) { + return "running"; + } + if (apiNodeList.some(n => n.status === "online" && n.quorum)) { + return "degraded"; } if (apiNodeList.some(n => n.status === "online" || n.status === "standby")) { - return "started"; + return "inoperative"; + } + if (apiNodeList.some(n => n.status === "unknown")) { + return "unknown"; } - return "stopped"; + return "offline"; }; +const hasCibInfo = (apiNodeList: ApiNode[]): Cluster["hasCibInfo"] => + apiNodeList.some(n => n.status === "online" || n.status === "standby"); export const processApiNodes = ( apiNodeList: ApiNode[], @@ -114,10 +125,12 @@ export const processApiNodes = ( nodeList: Node[]; nodesSeverity: StatusSeverity; clusterStatus: Cluster["status"]; + hasCibInfo: Cluster["hasCibInfo"]; } => ({ nodeList: apiNodeList.map(apiNode => toNode(apiNode, apiNodeAttrs[apiNode.name] || []), ), nodesSeverity: countNodesSeverity(apiNodeList), clusterStatus: getClusterStatus(apiNodeList), + hasCibInfo: hasCibInfo(apiNodeList), }); diff --git a/src/app/store/reducers/cluster/clusterStatus/reducer.ts b/src/app/store/reducers/cluster/clusterStatus/reducer.ts index 53d936925..aedcaf9ac 100644 --- a/src/app/store/reducers/cluster/clusterStatus/reducer.ts +++ b/src/app/store/reducers/cluster/clusterStatus/reducer.ts @@ -8,6 +8,7 @@ import { Cluster, ClusterStatusService } from "./types"; export const clusterStatusDefault: Cluster = { name: "", status: "unknown", + hasCibInfo: false, nodeList: [], resourceTree: [], fenceDeviceList: [], diff --git a/src/app/store/reducers/cluster/clusterStatus/types.ts b/src/app/store/reducers/cluster/clusterStatus/types.ts index 65d5cad3e..addc91a69 100644 --- a/src/app/store/reducers/cluster/clusterStatus/types.ts +++ b/src/app/store/reducers/cluster/clusterStatus/types.ts @@ -90,7 +90,8 @@ type ApiSbdConfig = Exclude< */ export type Cluster = { name: string; - status: "started" | "stopped" | "unknown"; + status: "running" | "degraded" | "inoperative" | "offline" | "unknown"; + hasCibInfo: boolean; nodeList: (( | { name: string; diff --git a/src/app/view/cluster/acl/lists/AclLists.tsx b/src/app/view/cluster/acl/lists/AclLists.tsx index 7488789a5..8c75e528b 100644 --- a/src/app/view/cluster/acl/lists/AclLists.tsx +++ b/src/app/view/cluster/acl/lists/AclLists.tsx @@ -12,7 +12,7 @@ const spacer: FlexProps["spacer"] = { default: "spacerNone" }; export const AclLists = () => { const [cluster] = useClusterSelector(selectors.getCluster); - if (cluster.status !== "started") { + if (!cluster.hasCibInfo) { return ( { )} {!isEditing && ( <> - {cluster.status !== "started" && ( + {!cluster.hasCibInfo && ( ["status"]; }) => { return ( diff --git a/src/app/view/share/ClusterStatusLabel.tsx b/src/app/view/share/ClusterStatusLabel.tsx index e3c8178cf..6dff7fa61 100644 --- a/src/app/view/share/ClusterStatusLabel.tsx +++ b/src/app/view/share/ClusterStatusLabel.tsx @@ -7,8 +7,10 @@ const statusColorMap: Record< Cluster["status"], React.ComponentProps["color"] > = { - started: "green", - stopped: "orange", + running: "green", + degraded: "gold", + inoperative: "orange", + offline: "red", unknown: "grey", }; diff --git a/src/app/view/share/nvpair/NVPairListView.tsx b/src/app/view/share/nvpair/NVPairListView.tsx index d93193b48..10b4ffb8a 100644 --- a/src/app/view/share/nvpair/NVPairListView.tsx +++ b/src/app/view/share/nvpair/NVPairListView.tsx @@ -17,7 +17,7 @@ export const NVPairListView = ({ }) => { const [cluster] = useClusterSelector(selectors.getCluster); - if (cluster.status !== "started") { + if (!cluster.hasCibInfo) { return ( { const [cluster] = useClusterSelector(selectors.getCluster); return React.useCallback( (title: string) => ({ - isDisabled: cluster.status !== "started", + isDisabled: !cluster.hasCibInfo, title, message: , }), From 8238cfbaa4a0278ed185470ffbbafc23ef22dd4a Mon Sep 17 00:00:00 2001 From: Ivan Devat Date: Fri, 21 Oct 2022 14:52:17 +0200 Subject: [PATCH 2/5] use softer button for cluster start in modal dialog --- .../properties/ClusterPropertiesPage.tsx | 2 +- src/app/view/share/ClusterStoppedInfo.tsx | 43 +++++++++++-------- .../emptyState/EmptyStateClusterStopped.tsx | 7 ++- .../useLauncherDisableClusterNotRunning.tsx | 2 +- 4 files changed, 34 insertions(+), 20 deletions(-) diff --git a/src/app/view/cluster/properties/ClusterPropertiesPage.tsx b/src/app/view/cluster/properties/ClusterPropertiesPage.tsx index 1ecd52633..9d9b798b5 100644 --- a/src/app/view/cluster/properties/ClusterPropertiesPage.tsx +++ b/src/app/view/cluster/properties/ClusterPropertiesPage.tsx @@ -98,7 +98,7 @@ export const ClusterPropertiesPage = () => { title="Cannot get cluster properties values from stopped cluster" className="pf-u-mb-sm" > - + )} { +export const ClusterStoppedInfo = ({ + startButton, +}: { + startButton?: "button" | "link"; +}) => { const clusterName = useSelectedClusterName(); return ( <>
Cluster is stopped. You can start cluster on detail tab.
-
- + -
+ ]} + /> + + )} ); }; diff --git a/src/app/view/share/emptyState/EmptyStateClusterStopped.tsx b/src/app/view/share/emptyState/EmptyStateClusterStopped.tsx index d3c2fc649..3a4b75277 100644 --- a/src/app/view/share/emptyState/EmptyStateClusterStopped.tsx +++ b/src/app/view/share/emptyState/EmptyStateClusterStopped.tsx @@ -9,5 +9,10 @@ export const EmptyStateClusterStopped = ({ }: { title: React.ReactNode; }) => { - return } />; + return ( + } + /> + ); }; diff --git a/src/app/view/share/toolbar/useLauncherDisableClusterNotRunning.tsx b/src/app/view/share/toolbar/useLauncherDisableClusterNotRunning.tsx index 093883fda..4d69e6ff9 100644 --- a/src/app/view/share/toolbar/useLauncherDisableClusterNotRunning.tsx +++ b/src/app/view/share/toolbar/useLauncherDisableClusterNotRunning.tsx @@ -10,7 +10,7 @@ export const useLauncherDisableClusterNotRunning = () => { (title: string) => ({ isDisabled: !cluster.hasCibInfo, title, - message: , + message: , }), [cluster], ); From 582c8ca109ec72b0e5dde7328decbd5d19fae085 Mon Sep 17 00:00:00 2001 From: Ivan Devat Date: Fri, 21 Oct 2022 15:22:06 +0200 Subject: [PATCH 3/5] deal with inaccessible resources in dashboard --- src/app/view/cluster/acl/lists/AclLists.tsx | 1 + .../constraints/ConstraintFilteredList.tsx | 1 + .../fenceDevices/list/FenceDeviceList.tsx | 1 + .../properties/ClusterPropertiesPage.tsx | 27 ++++++++++--------- .../cluster/resources/tree/ResourceTree.tsx | 1 + .../clusterList/DashboardCluster.tsx | 6 +++-- .../DashboardClusterCellSummary.tsx | 2 +- .../DashboardClusterFenceDevices.tsx | 11 ++++++++ .../clusterList/DashboardClusterResources.tsx | 10 +++++++ src/app/view/share/ClusterStoppedInfo.tsx | 15 ++++++++--- .../emptyState/EmptyStateClusterStopped.tsx | 6 ++++- src/app/view/share/nvpair/NVPairListView.tsx | 1 + .../useLauncherDisableClusterNotRunning.tsx | 4 ++- 13 files changed, 65 insertions(+), 21 deletions(-) diff --git a/src/app/view/cluster/acl/lists/AclLists.tsx b/src/app/view/cluster/acl/lists/AclLists.tsx index 8c75e528b..523e2aee0 100644 --- a/src/app/view/cluster/acl/lists/AclLists.tsx +++ b/src/app/view/cluster/acl/lists/AclLists.tsx @@ -16,6 +16,7 @@ export const AclLists = () => { return ( ); } diff --git a/src/app/view/cluster/constraints/ConstraintFilteredList.tsx b/src/app/view/cluster/constraints/ConstraintFilteredList.tsx index e30912648..a1902e442 100644 --- a/src/app/view/cluster/constraints/ConstraintFilteredList.tsx +++ b/src/app/view/cluster/constraints/ConstraintFilteredList.tsx @@ -83,6 +83,7 @@ export const ConstraintFilteredList = ({ return ( ); } diff --git a/src/app/view/cluster/fenceDevices/list/FenceDeviceList.tsx b/src/app/view/cluster/fenceDevices/list/FenceDeviceList.tsx index 69607bee2..52ee290ab 100644 --- a/src/app/view/cluster/fenceDevices/list/FenceDeviceList.tsx +++ b/src/app/view/cluster/fenceDevices/list/FenceDeviceList.tsx @@ -23,6 +23,7 @@ export const FenceDeviceList = ({ return ( ); } diff --git a/src/app/view/cluster/properties/ClusterPropertiesPage.tsx b/src/app/view/cluster/properties/ClusterPropertiesPage.tsx index 9d9b798b5..aaa6a73bc 100644 --- a/src/app/view/cluster/properties/ClusterPropertiesPage.tsx +++ b/src/app/view/cluster/properties/ClusterPropertiesPage.tsx @@ -65,14 +65,14 @@ export const ClusterPropertiesPage = () => { buttonsItems={[ ...(!isEditing ? [ - { - name: "edit-attributes", - run: () => setIsEditing(true), - launchDisable: launchDisable( - "Cannot edit cluster properties on stopped cluster", - ), - }, - ] + { + name: "edit-attributes", + run: () => setIsEditing(true), + launchDisable: launchDisable( + "Cannot edit cluster properties on stopped cluster", + ), + }, + ] : []), ]} /> @@ -98,7 +98,10 @@ export const ClusterPropertiesPage = () => { title="Cannot get cluster properties values from stopped cluster" className="pf-u-mb-sm" > - + )} { diff --git a/src/app/view/cluster/resources/tree/ResourceTree.tsx b/src/app/view/cluster/resources/tree/ResourceTree.tsx index 3f84df3d7..d1e47b8a0 100644 --- a/src/app/view/cluster/resources/tree/ResourceTree.tsx +++ b/src/app/view/cluster/resources/tree/ResourceTree.tsx @@ -25,6 +25,7 @@ export const ResourceTree = ({ return ( ); } diff --git a/src/app/view/dashboard/clusterList/DashboardCluster.tsx b/src/app/view/dashboard/clusterList/DashboardCluster.tsx index b386f8d27..b3c76b689 100644 --- a/src/app/view/dashboard/clusterList/DashboardCluster.tsx +++ b/src/app/view/dashboard/clusterList/DashboardCluster.tsx @@ -47,13 +47,15 @@ export const DashboardCluster = ({ cluster }: { cluster: Cluster }) => { diff --git a/src/app/view/dashboard/clusterList/DashboardClusterCellSummary.tsx b/src/app/view/dashboard/clusterList/DashboardClusterCellSummary.tsx index f869beee7..dc9dcae39 100644 --- a/src/app/view/dashboard/clusterList/DashboardClusterCellSummary.tsx +++ b/src/app/view/dashboard/clusterList/DashboardClusterCellSummary.tsx @@ -6,7 +6,7 @@ export const DashboardClusterCellSummary = ({ itemsCount, summaryStatus, }: { - itemsCount: number; + itemsCount: number | "?"; summaryStatus: React.ComponentProps["status"]; }) => { if (summaryStatus === "OK") { diff --git a/src/app/view/dashboard/clusterList/DashboardClusterFenceDevices.tsx b/src/app/view/dashboard/clusterList/DashboardClusterFenceDevices.tsx index 6eae6c2a3..48b9b851e 100644 --- a/src/app/view/dashboard/clusterList/DashboardClusterFenceDevices.tsx +++ b/src/app/view/dashboard/clusterList/DashboardClusterFenceDevices.tsx @@ -1,5 +1,6 @@ import { Cluster, FenceDevice } from "app/view/cluster/types"; import { + EmptyStateClusterStopped, EmptyStateNoItem, Link, StatusSign, @@ -34,6 +35,16 @@ export const DashboardClusterFenceDevices = ({ cluster: Cluster; }) => { const { sortState, compareItems } = SortableTh.useSorting("NAME"); + + if (!cluster.hasCibInfo) { + return ( + + ); + } + if (cluster.fenceDeviceList.length === 0) { return ( { const { sortState, compareItems } = SortableTh.useSorting("NAME"); + if (!cluster.hasCibInfo) { + return ( + + ); + } + if (cluster.resourceTree.length === 0) { return ( { - const clusterName = useSelectedClusterName(); return ( <>
Cluster is stopped. You can start cluster on detail tab.
@@ -18,8 +20,13 @@ export const ClusterStoppedInfo = ({ { name: "start cluster", confirm: { - title: "Start cluster?", - description: "Start the on all nodes", + title: "Start the cluster?", + description: ( + + Start the cluster{" "} + on all nodes + + ), action: { type: "DASHBOARD.CLUSTER.START", payload: { clusterName }, diff --git a/src/app/view/share/emptyState/EmptyStateClusterStopped.tsx b/src/app/view/share/emptyState/EmptyStateClusterStopped.tsx index 3a4b75277..60dc2529b 100644 --- a/src/app/view/share/emptyState/EmptyStateClusterStopped.tsx +++ b/src/app/view/share/emptyState/EmptyStateClusterStopped.tsx @@ -6,13 +6,17 @@ import { EmptyStateConfigure } from "./EmptyStateConfigure"; export const EmptyStateClusterStopped = ({ title, + clusterName, }: { title: React.ReactNode; + clusterName: string; }) => { return ( } + message={ + + } /> ); }; diff --git a/src/app/view/share/nvpair/NVPairListView.tsx b/src/app/view/share/nvpair/NVPairListView.tsx index 10b4ffb8a..ace9a85be 100644 --- a/src/app/view/share/nvpair/NVPairListView.tsx +++ b/src/app/view/share/nvpair/NVPairListView.tsx @@ -21,6 +21,7 @@ export const NVPairListView = ({ return ( ); } diff --git a/src/app/view/share/toolbar/useLauncherDisableClusterNotRunning.tsx b/src/app/view/share/toolbar/useLauncherDisableClusterNotRunning.tsx index 4d69e6ff9..c7e416c73 100644 --- a/src/app/view/share/toolbar/useLauncherDisableClusterNotRunning.tsx +++ b/src/app/view/share/toolbar/useLauncherDisableClusterNotRunning.tsx @@ -10,7 +10,9 @@ export const useLauncherDisableClusterNotRunning = () => { (title: string) => ({ isDisabled: !cluster.hasCibInfo, title, - message: , + message: ( + + ), }), [cluster], ); From e0dd2676a2c12fe9057abbc493b4c5895e28207c Mon Sep 17 00:00:00 2001 From: Ivan Devat Date: Sat, 22 Oct 2022 12:49:57 +0200 Subject: [PATCH 4/5] hide acl status flag when cluster is not online --- src/app/view/cluster/acl/AclPage.tsx | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/app/view/cluster/acl/AclPage.tsx b/src/app/view/cluster/acl/AclPage.tsx index 4c96dc56a..6f055e0b0 100644 --- a/src/app/view/cluster/acl/AclPage.tsx +++ b/src/app/view/cluster/acl/AclPage.tsx @@ -74,9 +74,8 @@ export const AclPage = () => { label: `${aclEnabled ? "Disable" : "Enable"} ACL`, confirm: { title: aclEnabled ? "Disable ACL" : "Enable ACL", - description: `${ - aclEnabled ? "Disable" : "Enable" - } access control lists.`, + description: `${aclEnabled ? "Disable" : "Enable" + } access control lists.`, action: { type: "CLUSTER.PROPERTIES.UPDATE", key: { clusterName }, @@ -93,14 +92,16 @@ export const AclPage = () => { }, ]} after={ - <> - - - - - + cluster.hasCibInfo ? ( + <> + + + + + + ) : null } /> From 9a6455977b55e4c61f55ae2c8b931004ed874d81 Mon Sep 17 00:00:00 2001 From: Ivan Devat Date: Sat, 22 Oct 2022 13:00:59 +0200 Subject: [PATCH 5/5] fix tests --- src/test/scenes/dashboard/dashboard.test.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/scenes/dashboard/dashboard.test.ts b/src/test/scenes/dashboard/dashboard.test.ts index c3bfea2aa..e147096c1 100644 --- a/src/test/scenes/dashboard/dashboard.test.ts +++ b/src/test/scenes/dashboard/dashboard.test.ts @@ -46,7 +46,9 @@ describe("Dashboard scene", () => { await displayClusters(); const clusterInfoList = await page.$$eval(CLUSTERS, clusterElements => clusterElements.map(e => ({ - name: e.querySelector("[data-test='name']")?.textContent ?? "", + name: + e.querySelector("[data-test='name'] strong")?.textContent?.trim() + ?? "", issuesTotal: e.querySelector("[data-test='issues']")?.textContent ?? "", nodesTotal: e.querySelector("[data-test='nodes']")?.textContent ?? "", resourcesTotal: