Skip to content

Commit 4b79e2b

Browse files
authored
CONSOLE-3899: Add Node CSR handling (#13493)
* CONSOLE-3899: Add Node CSR handling * fixup! CONSOLE-3899: Add Node CSR handling * fixup! fixup! CONSOLE-3899: Add Node CSR handling * fixup! fixup! fixup! CONSOLE-3899: Add Node CSR handling
1 parent 9fb8cc0 commit 4b79e2b

24 files changed

Lines changed: 1128 additions & 522 deletions

File tree

frontend/packages/console-app/console-extensions.json

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1794,5 +1794,31 @@
17941794
}
17951795
}
17961796
}
1797+
},
1798+
{
1799+
"type": "console.node/status",
1800+
"properties": {
1801+
"title": "%console-app~Scheduling disabled%",
1802+
"PopoverContent": { "$codeRef": "nodeStatus.MarkAsSchedulablePopover" },
1803+
"isActive": { "$codeRef": "nodeStatus.isUnschedulableActive" }
1804+
}
1805+
},
1806+
{
1807+
"type": "console.node/status",
1808+
"properties": {
1809+
"title": "%console-app~Approval required%",
1810+
"PopoverContent": { "$codeRef": "nodeStatus.ServerCSRPopoverContent" },
1811+
"isActive": { "$codeRef": "nodeStatus.isCSRActive" },
1812+
"resources": {
1813+
"csrs": {
1814+
"groupVersionKind": {
1815+
"group": "certificates.k8s.io",
1816+
"kind": "CertificateSigningRequest",
1817+
"version": "v1"
1818+
},
1819+
"isList": true
1820+
}
1821+
}
1822+
}
17971823
}
17981824
]

frontend/packages/console-app/locales/en/console-app.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,8 @@
165165
"Default filesystem type to request": "Default filesystem type to request",
166166
"Name of the secret to use for obtaining the StorageOS API credentials": "Name of the secret to use for obtaining the StorageOS API credentials",
167167
"Namespace where the API configuration secret is located": "Namespace where the API configuration secret is located",
168+
"Scheduling disabled": "Scheduling disabled",
169+
"Approval required": "Approval required",
168170
"Delete {{kind}}": "Delete {{kind}}",
169171
"Edit {{kind}}": "Edit {{kind}}",
170172
"Edit labels": "Edit labels",
@@ -422,13 +424,20 @@
422424
"{{formattedCores}} cores / {{totalCores}} cores": "{{formattedCores}} cores / {{totalCores}} cores",
423425
"Ready": "Ready",
424426
"Not Ready": "Not Ready",
427+
"Discovered": "Discovered",
425428
"control-plane": "control-plane",
426429
"worker": "worker",
430+
"Node status": "Node status",
427431
"This node's {{conditionDescription}}. Performance may be degraded.": "This node's {{conditionDescription}}. Performance may be degraded.",
428432
"<0>To use host binaries, run <1>chroot /host</1></0>": "<0>To use host binaries, run <1>chroot /host</1></0>",
429433
"The debug pod failed. ": "The debug pod failed. ",
434+
"This node has requested to join the cluster. After approving its certificate signing request the node will begin running workloads.": "This node has requested to join the cluster. After approving its certificate signing request the node will begin running workloads.",
435+
"This node has a pending server certificate signing request. Approve the request to enable all networking functionality on this node.": "This node has a pending server certificate signing request. Approve the request to enable all networking functionality on this node.",
436+
"Request": "Request",
437+
"Approve": "Approve",
438+
"Deny": "Deny",
439+
"Certificate approval required": "Certificate approval required",
430440
"An error occurred. Please try again": "An error occurred. Please try again",
431-
"Scheduling disabled": "Scheduling disabled",
432441
"No new Pods or workloads will be placed on this Node until it's marked as schedulable.": "No new Pods or workloads will be placed on this Node until it's marked as schedulable.",
433442
"Mark as schedulable": "Mark as schedulable",
434443
"Min available {{minAvailable}} of {{count}} pod_one": "Min available {{minAvailable}} of {{count}} pod",

frontend/packages/console-app/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@
4646
"perspectiveConfiguration": "src/components/detect-perspective/PerspectiveConfiguration.tsx",
4747
"dynamicPluginsHealthResource": "src/components/dashboards-page/dynamic-plugins-health-resource",
4848
"storageProvisioners": "src/components/storage/StorageClassProviders",
49-
"storageProvisionerDocs": "src/components/storage/Documentation"
49+
"storageProvisionerDocs": "src/components/storage/Documentation",
50+
"nodeStatus": "src/components/nodes/status"
5051
}
5152
}
5253
}

frontend/packages/console-app/src/components/nodes/NodeDetailsOverview.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import {
2424
import NodeUptime from './node-dashboard/NodeUptime';
2525
import NodeIPList from './NodeIPList';
2626
import NodeStatus from './NodeStatus';
27-
import MarkAsSchedulablePopover from './popovers/MarkAsSchedulablePopover';
2827

2928
type NodeDetailsOverviewProps = {
3029
node: NodeKind;
@@ -52,11 +51,7 @@ const NodeDetailsOverview: React.FC<NodeDetailsOverviewProps> = ({ node }) => {
5251
<dd>{node.metadata.name || '-'}</dd>
5352
<dt>{t('console-app~Status')}</dt>
5453
<dd>
55-
{!node.spec.unschedulable ? (
56-
<NodeStatus node={node} showPopovers />
57-
) : (
58-
<MarkAsSchedulablePopover node={node} />
59-
)}
54+
<NodeStatus node={node} />
6055
</dd>
6156
<dt>{t('console-app~External ID')}</dt>
6257
<dd>{_.get(node, 'spec.externalID', '-')}</dd>
Lines changed: 62 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
import * as React from 'react';
2+
import { Stack, StackItem } from '@patternfly/react-core';
23
import * as _ from 'lodash';
34
import { useTranslation } from 'react-i18next';
5+
import { PopoverStatus, NodeStatus } from '@console/dynamic-plugin-sdk';
46
import { humanizeBinaryBytes, humanizeNumber } from '@console/internal/components/utils';
57
import { NodeKind } from '@console/internal/module/k8s';
6-
import {
7-
getNodeSecondaryStatus,
8-
NodeUnschedulableStatus,
9-
Status,
10-
SecondaryStatus,
11-
} from '@console/shared';
8+
import { Status, SecondaryStatus } from '@console/shared';
129
import ConsumerPopover from '@console/shared/src/components/dashboard/utilization-card/TopConsumerPopover';
10+
import { ErrorBoundary } from '@console/shared/src/components/error';
1311
import { PressureQueries, Condition } from '../../queries';
1412
import { nodeStatus } from '../../status/node';
13+
import { GetNodeStatusExtensions, useNodeStatusExtensions } from './useNodeStatusExtensions';
1514

1615
const conditionDescriptionMap = Object.freeze({
1716
[Condition.DISK_PRESSURE]: 'available disk capacity is low',
@@ -34,40 +33,75 @@ const getDegradedStates = (node: NodeKind): Condition[] => {
3433
.map(({ type }) => type as Condition);
3534
};
3635

37-
const NodeStatus: React.FC<NodeStatusProps> = ({ node, showPopovers = false, className }) => {
38-
const status = showPopovers ? getDegradedStates(node) : [];
36+
type NodeStatusWithExtensionsProps = {
37+
node: NodeKind;
38+
statusExtensions: GetNodeStatusExtensions;
39+
className?: string;
40+
};
41+
42+
export const NodeStatusWithExtensions: React.FC<NodeStatusWithExtensionsProps> = ({
43+
node,
44+
className,
45+
statusExtensions,
46+
}) => {
3947
const { t } = useTranslation();
48+
49+
const { popoverContent, secondaryStatuses } = React.useMemo(() => statusExtensions(node), [
50+
statusExtensions,
51+
node,
52+
]);
53+
54+
const mainStatus = <Status status={nodeStatus(node)} className={className} />;
55+
4056
return (
4157
<>
42-
{!node.spec.unschedulable ? (
43-
<Status status={nodeStatus(node)} className={className} />
58+
{popoverContent.length ? (
59+
<PopoverStatus title={t('console-app~Node status')} statusBody={mainStatus}>
60+
<Stack>
61+
{popoverContent.map(({ content, uid }) => (
62+
<ErrorBoundary key={uid}>
63+
<StackItem>{content}</StackItem>
64+
</ErrorBoundary>
65+
))}
66+
</Stack>
67+
</PopoverStatus>
4468
) : (
45-
<NodeUnschedulableStatus status={nodeStatus(node)} className={className} />
69+
mainStatus
4670
)}
47-
<SecondaryStatus status={getNodeSecondaryStatus(node)} />
48-
{status.length > 0 &&
49-
status.map((item) => (
50-
<div key={item}>
51-
<ConsumerPopover
52-
title={_.startCase(item)}
53-
current={_.startCase(item)}
54-
consumers={PressureQueries[item](node.metadata.name)}
55-
humanize={humanizeMap[item]}
56-
description={t(
57-
"console-app~This node's {{conditionDescription}}. Performance may be degraded.",
58-
{ conditionDescription: conditionDescriptionMap[item] },
59-
)}
60-
/>
61-
</div>
62-
))}
71+
<SecondaryStatus status={secondaryStatuses} />
72+
{getDegradedStates(node)?.map((item) => (
73+
<div key={item}>
74+
<ConsumerPopover
75+
title={_.startCase(item)}
76+
current={_.startCase(item)}
77+
consumers={PressureQueries[item](node.metadata.name)}
78+
humanize={humanizeMap[item]}
79+
description={t(
80+
"console-app~This node's {{conditionDescription}}. Performance may be degraded.",
81+
{ conditionDescription: conditionDescriptionMap[item] },
82+
)}
83+
/>
84+
</div>
85+
))}
6386
</>
6487
);
6588
};
6689

6790
type NodeStatusProps = {
6891
node: NodeKind;
69-
showPopovers?: boolean;
7092
className?: string;
7193
};
7294

95+
const NodeStatus: React.FC<NodeStatusProps> = ({ node, className }) => {
96+
const statusExtensions = useNodeStatusExtensions();
97+
98+
return (
99+
<NodeStatusWithExtensions
100+
node={node}
101+
className={className}
102+
statusExtensions={statusExtensions}
103+
/>
104+
);
105+
};
106+
73107
export default NodeStatus;

0 commit comments

Comments
 (0)