Skip to content

Commit 1169770

Browse files
committed
Add new operators to virtualization bundle
1 parent 7335061 commit 1169770

15 files changed

+474
-5
lines changed

libs/locales/lib/en/translation.json

+10
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,8 @@
336336
"ai:Failed to update the AgentServiceConfig": "Failed to update the AgentServiceConfig",
337337
"ai:Failed validations:": "Failed validations:",
338338
"ai:Failing infrastructure environment": "Failing infrastructure environment",
339+
"ai:Fence Agents Remediation": "Fence Agents Remediation",
340+
"ai:Fence Agents Remediation requirements": "Fence Agents Remediation requirements",
339341
"ai:File is not structured correctly. Use the template to use the right file structure.": "File is not structured correctly. Use the template to use the right file structure.",
340342
"ai:File size is too big. Upload a new {{maxFileSizeKb}} Kb or less.": "File size is too big. Upload a new file that is {{maxFileSizeKb}} Kb or less.",
341343
"ai:File type is not supported. File type must be {{acceptedFiles}}.": "File type is not supported. File type must be {{acceptedFiles}}.",
@@ -476,6 +478,8 @@
476478
"ai:Keep the field empty to match <bold>any</bold> location.": "Keep the field empty to match <bold>any</bold> location.",
477479
"ai:Kernel Module Management": "Kernel Module Management",
478480
"ai:Kernel Module Management requirements": "Kernel Module Management requirements",
481+
"ai:Kube Descheduler": "Kube Descheduler",
482+
"ai:Kube Descheduler requirements": "Kube Descheduler requirements",
479483
"ai:Kubeconfig is empty.": "Kubeconfig is empty.",
480484
"ai:Labels": "Labels",
481485
"ai:Labels matching hosts": "Labels matching hosts",
@@ -591,6 +595,10 @@
591595
"ai:No version selected": "No version selected",
592596
"ai:Node Feature Discovery": "Node Feature Discovery",
593597
"ai:Node Feature Discovery requirements": "Node Feature Discovery requirements",
598+
"ai:Node Healthcheck": "Node Healthcheck",
599+
"ai:Node Healthcheck requirements": "Node Healthcheck requirements",
600+
"ai:Node Maintenace": "Node Maintenace",
601+
"ai:Node Maintenance requirements": "Node Maintenance requirements",
594602
"ai:Nodepool": "Nodepool",
595603
"ai:Nodepool conditions": "Nodepool conditions",
596604
"ai:Nodepool name": "Nodepool name",
@@ -731,6 +739,8 @@
731739
"ai:Select one or multiple locations to choose the hosts from.": "Select one or multiple locations of the hosts.",
732740
"ai:selected": "selected",
733741
"ai:Selected image does not support arm64": "Selected image does not support arm64",
742+
"ai:Self Node Remediation": "Self Node Remediation",
743+
"ai:Self Node Remediation requirements": "Self Node Remediation requirements",
734744
"ai:Serial": "Serial",
735745
"ai:Serial number": "Serial number",
736746
"ai:Serverless": "Serverless",

libs/types/assisted-installer-service.d.ts

+18-3
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,12 @@ export type ClusterValidationId =
658658
| 'authorino-requirements-satisfied'
659659
| 'nmstate-requirements-satisfied'
660660
| 'amd-gpu-requirements-satisfied'
661-
| 'kmm-requirements-satisfied';
661+
| 'kmm-requirements-satisfied'
662+
| 'node-healthcheck-requirements-satisfied'
663+
| 'self-node-remediation-requirements-satisfied'
664+
| 'fence-agents-remediation-requirements-satisfied'
665+
| 'node-maintenance-requirements-satisfied'
666+
| 'kube-descheduler-requirements-satisfied';
662667
export interface CompletionParams {
663668
isSuccess: boolean;
664669
errorInfo?: string;
@@ -1053,7 +1058,12 @@ export type FeatureSupportLevelId =
10531058
| 'USER_MANAGED_LOAD_BALANCER'
10541059
| 'NMSTATE'
10551060
| 'AMD_GPU'
1056-
| 'KMM';
1061+
| 'KMM'
1062+
| 'NODE_HEALTHCHECK'
1063+
| 'SELF_NODE_REMEDIATION'
1064+
| 'FENCE_AGENTS_REMEDIATION'
1065+
| 'NODE_MAINTENANCE'
1066+
| 'KUBE_DESCHEDULER';
10571067
/**
10581068
* Cluster finalizing stage managed by controller
10591069
*/
@@ -1609,7 +1619,12 @@ export type HostValidationId =
16091619
| 'mtu-valid'
16101620
| 'nmstate-requirements-satisfied'
16111621
| 'amd-gpu-requirements-satisfied'
1612-
| 'kmm-requirements-satisfied';
1622+
| 'kmm-requirements-satisfied'
1623+
| 'node-healthcheck-requirements-satisfied'
1624+
| 'self-node-remediation-requirements-satisfied'
1625+
| 'fence-agents-remediation-requirements-satisfied'
1626+
| 'node-maintenance-requirements-satisfied'
1627+
| 'kube-descheduler-requirements-satisfied';
16131628
/**
16141629
* Explicit ignition endpoint overrides the default ignition endpoint.
16151630
*/

libs/ui-lib/lib/common/config/constants.ts

+30
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,11 @@ export const hostValidationLabels = (t: TFunction): { [key in HostValidationId]:
140140
'nmstate-requirements-satisfied': '',
141141
'amd-gpu-requirements-satisfied': t('ai:AMD GPU requirements'),
142142
'kmm-requirements-satisfied': t('ai:Kernel Module Management requirements'),
143+
'node-healthcheck-requirements-satisfied': t('ai:Node Healthcheck requirements'),
144+
'self-node-remediation-requirements-satisfied': t('ai:Self Node Remediation requirements'),
145+
'fence-agents-remediation-requirements-satisfied': t('ai:Fence Agents Remediation requirements'),
146+
'node-maintenance-requirements-satisfied': t('ai:Node Maintenance requirements'),
147+
'kube-descheduler-requirements-satisfied': t('ai:Kube Descheduler requirements'),
143148
});
144149

145150
export const hostValidationFailureHints = (
@@ -202,6 +207,11 @@ export const hostValidationFailureHints = (
202207
'nmstate-requirements-satisfied': '',
203208
'amd-gpu-requirements-satisfied': '',
204209
'kmm-requirements-satisfied': '',
210+
'node-healthcheck-requirements-satisfied': '',
211+
'self-node-remediation-requirements-satisfied': '',
212+
'fence-agents-remediation-requirements-satisfied': '',
213+
'node-maintenance-requirements-satisfied': '',
214+
'kube-descheduler-requirements-satisfied': '',
205215
});
206216

207217
export const clusterValidationLabels = (
@@ -307,6 +317,11 @@ export const OPERATOR_NAME_NMSTATE = 'nmstate';
307317
export const OPERATOR_NAME_AUTHORINO = 'authorino';
308318
export const OPERATOR_NAME_AMD_GPU = 'amd-gpu';
309319
export const OPERATOR_NAME_KMM = 'kmm';
320+
export const OPERATOR_NAME_NODE_HEALTHCHECK = 'node-healthcheck';
321+
export const OPERATOR_NAME_SELF_NODE_REMEDIATION = 'self-node-remediation';
322+
export const OPERATOR_NAME_FENCE_AGENTS_REMEDIATION = 'fence-agents-remediation';
323+
export const OPERATOR_NAME_NODE_MAINTENANCE = 'node-maintenance';
324+
export const OPERATOR_NAME_KUBE_DESCHEDULER = 'kube-descheduler';
310325

311326
const OperatorNames = [
312327
OPERATOR_NAME_CNV,
@@ -327,6 +342,11 @@ const OperatorNames = [
327342
OPERATOR_NAME_AUTHORINO,
328343
OPERATOR_NAME_AMD_GPU,
329344
OPERATOR_NAME_KMM,
345+
OPERATOR_NAME_NODE_HEALTHCHECK,
346+
OPERATOR_NAME_SELF_NODE_REMEDIATION,
347+
OPERATOR_NAME_FENCE_AGENTS_REMEDIATION,
348+
OPERATOR_NAME_NODE_MAINTENANCE,
349+
OPERATOR_NAME_KUBE_DESCHEDULER,
330350
];
331351
export const ExposedOperatorNames = [
332352
OPERATOR_NAME_CNV,
@@ -346,6 +366,11 @@ export const ExposedOperatorNames = [
346366
OPERATOR_NAME_AUTHORINO,
347367
OPERATOR_NAME_AMD_GPU,
348368
OPERATOR_NAME_KMM,
369+
OPERATOR_NAME_NODE_HEALTHCHECK,
370+
OPERATOR_NAME_SELF_NODE_REMEDIATION,
371+
OPERATOR_NAME_FENCE_AGENTS_REMEDIATION,
372+
OPERATOR_NAME_NODE_MAINTENANCE,
373+
OPERATOR_NAME_KUBE_DESCHEDULER,
349374
];
350375

351376
export type OperatorName = (typeof OperatorNames)[number];
@@ -393,6 +418,11 @@ export const operatorLabels = (
393418
[OPERATOR_NAME_AUTHORINO]: t('ai:Authorino'),
394419
[OPERATOR_NAME_AMD_GPU]: t('ai:AMD GPU'),
395420
[OPERATOR_NAME_KMM]: t('ai:Kernel Module Management'),
421+
[OPERATOR_NAME_NODE_HEALTHCHECK]: t('ai:Node Healthcheck'),
422+
[OPERATOR_NAME_SELF_NODE_REMEDIATION]: t('ai:Self Node Remediation'),
423+
[OPERATOR_NAME_FENCE_AGENTS_REMEDIATION]: t('ai:Fence Agents Remediation'),
424+
[OPERATOR_NAME_NODE_MAINTENANCE]: t('ai:Node Maintenace'),
425+
[OPERATOR_NAME_KUBE_DESCHEDULER]: t('ai:Kube Descheduler'),
396426
};
397427
};
398428

libs/ui-lib/lib/common/config/docs_links.ts

+17
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,23 @@ export const getLvmsDocsLink = (ocpVersion?: string) =>
105105
ocpVersion,
106106
)}/html/storage/configuring-persistent-storage#overview-of-lvm-storage-functionality_ways-to-provision-local-storage`;
107107

108+
export const NODE_HEALTHCHECK_LINK =
109+
'https://docs.redhat.com/en/documentation/workload_availability_for_red_hat_openshift/latest/html/remediation_fencing_and_maintenance/node-health-check-operator';
110+
111+
export const SELF_NODE_REMEDIATION_LINK =
112+
'https://docs.redhat.com/en/documentation/workload_availability_for_red_hat_openshift/latest/html/remediation_fencing_and_maintenance/self-node-remediation-operator-remediate-nodes';
113+
114+
export const FENCE_AGENTS_REMEDIATION_LINK =
115+
'https://docs.redhat.com/en/documentation/workload_availability_for_red_hat_openshift/latest/html/remediation_fencing_and_maintenance/fence-agents-remediation-operator-remediate-nodes';
116+
117+
export const NODE_MAINTENANCE_LINK =
118+
'https://docs.redhat.com/en/documentation/workload_availability_for_red_hat_openshift/latest/html/remediation_fencing_and_maintenance/node-maintenance-operator';
119+
120+
export const getKubeDeschedulerLink = (ocpVersion?: string) =>
121+
`https://docs.redhat.com/en/documentation/openshift_container_platform/${getShortOpenshiftVersion(
122+
ocpVersion,
123+
)}/html/nodes/controlling-pod-placement-onto-nodes-scheduling#descheduler`;
124+
108125
//Others
109126
export const REDHAT_CONSOLE_OPENSHIFT = 'https://console.redhat.com/openshift';
110127

libs/ui-lib/lib/common/types/clusters.ts

+5
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,11 @@ export type OperatorsValues = V2ClusterUpdateParams & {
7676
useNvidiaGpu: boolean;
7777
useAmdGpu: boolean;
7878
useKmm: boolean;
79+
useNodeHealthcheck: boolean;
80+
useSelfNodeRemediation: boolean;
81+
useFenceAgentsRemediation: boolean;
82+
useNodeMaintenance: boolean;
83+
useKubeDescheduler: boolean;
7984
};
8085

8186
export type SupportedPlatformType = Extract<PlatformType, 'vsphere' | 'nutanix' | 'external'>;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import React from 'react';
2+
import { FormGroup, HelperText, HelperTextItem, Tooltip } from '@patternfly/react-core';
3+
import { getFieldId, FENCE_AGENTS_REMEDIATION_LINK } from '../../../../common';
4+
import { ExternalLinkAltIcon } from '@patternfly/react-icons/dist/js/icons/external-link-alt-icon';
5+
import { OcmCheckboxField } from '../../ui/OcmFormFields';
6+
import NewFeatureSupportLevelBadge from '../../../../common/components/newFeatureSupportLevels/NewFeatureSupportLevelBadge';
7+
import { SupportLevel } from '@openshift-assisted/types/./assisted-installer-service';
8+
9+
const FENCE_AGENTS_REMEDIATION_FIELD_NAME = 'useFenceAgentsRemediation';
10+
const FENCE_AGENTS_REMEDIATION_FEATURE_ID = 'FENCE_AGENTS_REMEDIATION';
11+
12+
const FenceAgentsRemediationLabel = ({
13+
disabledReason,
14+
supportLevel,
15+
}: {
16+
disabledReason?: string;
17+
supportLevel?: SupportLevel;
18+
}) => {
19+
return (
20+
<>
21+
<Tooltip hidden={!disabledReason} content={disabledReason}>
22+
<span>Fence Agents Remediation </span>
23+
</Tooltip>
24+
<NewFeatureSupportLevelBadge
25+
featureId={FENCE_AGENTS_REMEDIATION_FEATURE_ID}
26+
supportLevel={supportLevel}
27+
/>
28+
</>
29+
);
30+
};
31+
32+
const FenceAgentsRemediationHelperText = () => {
33+
return (
34+
<HelperText>
35+
<HelperTextItem variant="indeterminate">
36+
Externally fences failed nodes using power controllers.{' '}
37+
<a href={FENCE_AGENTS_REMEDIATION_LINK} target="_blank" rel="noopener noreferrer">
38+
{'Learn more'} <ExternalLinkAltIcon />
39+
</a>
40+
</HelperTextItem>
41+
</HelperText>
42+
);
43+
};
44+
45+
const FenceAgentsRemediationCheckbox = ({
46+
disabledReason,
47+
supportLevel,
48+
}: {
49+
disabledReason?: string;
50+
supportLevel?: SupportLevel | undefined;
51+
}) => {
52+
const fieldId = getFieldId(FENCE_AGENTS_REMEDIATION_FIELD_NAME, 'input');
53+
54+
return (
55+
<FormGroup isInline fieldId={fieldId}>
56+
<OcmCheckboxField
57+
name={FENCE_AGENTS_REMEDIATION_FIELD_NAME}
58+
label={
59+
<FenceAgentsRemediationLabel
60+
disabledReason={disabledReason}
61+
supportLevel={supportLevel}
62+
/>
63+
}
64+
helperText={<FenceAgentsRemediationHelperText />}
65+
isDisabled={!!disabledReason}
66+
/>
67+
</FormGroup>
68+
);
69+
};
70+
71+
export default FenceAgentsRemediationCheckbox;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import React from 'react';
2+
import { FormGroup, HelperText, HelperTextItem, Tooltip } from '@patternfly/react-core';
3+
import { getFieldId, NODE_HEALTHCHECK_LINK } from '../../../../common';
4+
import { ExternalLinkAltIcon } from '@patternfly/react-icons/dist/js/icons/external-link-alt-icon';
5+
import { OcmCheckboxField } from '../../ui/OcmFormFields';
6+
import NewFeatureSupportLevelBadge from '../../../../common/components/newFeatureSupportLevels/NewFeatureSupportLevelBadge';
7+
import { SupportLevel } from '@openshift-assisted/types/./assisted-installer-service';
8+
9+
const KUBE_DESCHEDULER_FIELD_NAME = 'useKubeDescheduler';
10+
const KUBE_DESCHEDULER_FEATURE_ID = 'KUBE_DESCHEDULER';
11+
12+
const KubeDeschedulerLabel = ({
13+
disabledReason,
14+
supportLevel,
15+
}: {
16+
disabledReason?: string;
17+
supportLevel?: SupportLevel;
18+
}) => {
19+
return (
20+
<>
21+
<Tooltip hidden={!disabledReason} content={disabledReason}>
22+
<span>Kube Descheduler </span>
23+
</Tooltip>
24+
<NewFeatureSupportLevelBadge
25+
featureId={KUBE_DESCHEDULER_FEATURE_ID}
26+
supportLevel={supportLevel}
27+
/>
28+
</>
29+
);
30+
};
31+
32+
const KubeDeschedulerHelperText = () => {
33+
return (
34+
<HelperText>
35+
<HelperTextItem variant="indeterminate">
36+
Evicts pods to reschedule them onto more suitable nodes.{' '}
37+
<a href={NODE_HEALTHCHECK_LINK} target="_blank" rel="noopener noreferrer">
38+
{'Learn more'} <ExternalLinkAltIcon />
39+
</a>
40+
</HelperTextItem>
41+
</HelperText>
42+
);
43+
};
44+
45+
const KubeDeschedulerCheckbox = ({
46+
disabledReason,
47+
supportLevel,
48+
}: {
49+
disabledReason?: string;
50+
supportLevel?: SupportLevel | undefined;
51+
}) => {
52+
const fieldId = getFieldId(KUBE_DESCHEDULER_FIELD_NAME, 'input');
53+
54+
return (
55+
<FormGroup isInline fieldId={fieldId}>
56+
<OcmCheckboxField
57+
name={KUBE_DESCHEDULER_FIELD_NAME}
58+
label={<KubeDeschedulerLabel disabledReason={disabledReason} supportLevel={supportLevel} />}
59+
helperText={<KubeDeschedulerHelperText />}
60+
isDisabled={!!disabledReason}
61+
/>
62+
</FormGroup>
63+
);
64+
};
65+
66+
export default KubeDeschedulerCheckbox;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import React from 'react';
2+
import { FormGroup, HelperText, HelperTextItem, Tooltip } from '@patternfly/react-core';
3+
import { getFieldId, NODE_HEALTHCHECK_LINK } from '../../../../common';
4+
import { ExternalLinkAltIcon } from '@patternfly/react-icons/dist/js/icons/external-link-alt-icon';
5+
import { OcmCheckboxField } from '../../ui/OcmFormFields';
6+
import NewFeatureSupportLevelBadge from '../../../../common/components/newFeatureSupportLevels/NewFeatureSupportLevelBadge';
7+
import { SupportLevel } from '@openshift-assisted/types/./assisted-installer-service';
8+
9+
const NODE_HEALTHCHECK_FIELD_NAME = 'useNodeHealthcheck';
10+
const NODE_HEALTHCHECK_FEATURE_ID = 'NODE_HEALTHCHECK';
11+
12+
const NodeHealthcheckLabel = ({
13+
disabledReason,
14+
supportLevel,
15+
}: {
16+
disabledReason?: string;
17+
supportLevel?: SupportLevel;
18+
}) => {
19+
return (
20+
<>
21+
<Tooltip hidden={!disabledReason} content={disabledReason}>
22+
<span>Node Healthcheck </span>
23+
</Tooltip>
24+
<NewFeatureSupportLevelBadge
25+
featureId={NODE_HEALTHCHECK_FEATURE_ID}
26+
supportLevel={supportLevel}
27+
/>
28+
</>
29+
);
30+
};
31+
32+
const NodeHealthcheckHelperText = () => {
33+
return (
34+
<HelperText>
35+
<HelperTextItem variant="indeterminate">
36+
Identify Unhealthy Nodes.{' '}
37+
<a href={NODE_HEALTHCHECK_LINK} target="_blank" rel="noopener noreferrer">
38+
{'Learn more'} <ExternalLinkAltIcon />
39+
</a>
40+
</HelperTextItem>
41+
</HelperText>
42+
);
43+
};
44+
45+
const NodeHealthcheckCheckbox = ({
46+
disabledReason,
47+
supportLevel,
48+
}: {
49+
disabledReason?: string;
50+
supportLevel?: SupportLevel | undefined;
51+
}) => {
52+
const fieldId = getFieldId(NODE_HEALTHCHECK_FIELD_NAME, 'input');
53+
54+
return (
55+
<FormGroup isInline fieldId={fieldId}>
56+
<OcmCheckboxField
57+
name={NODE_HEALTHCHECK_FIELD_NAME}
58+
label={<NodeHealthcheckLabel disabledReason={disabledReason} supportLevel={supportLevel} />}
59+
helperText={<NodeHealthcheckHelperText />}
60+
isDisabled={!!disabledReason}
61+
/>
62+
</FormGroup>
63+
);
64+
};
65+
66+
export default NodeHealthcheckCheckbox;

0 commit comments

Comments
 (0)