@openshift-assisted/ui-lib 2.42.1 → 2.42.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/@types/common/components/operators/operatorSpecs.d.ts +10 -3
- package/build/@types/common/components/operators/operatorSpecs.d.ts.map +1 -1
- package/build/@types/common/components/operators/test.d.ts +50 -0
- package/build/@types/common/components/operators/test.d.ts.map +1 -0
- package/build/@types/ocm/components/clusterConfiguration/ControlPlaneNodesDropdown.d.ts.map +1 -1
- package/build/@types/ocm/components/clusterConfiguration/operators/OperatorCheckbox.d.ts +2 -1
- package/build/@types/ocm/components/clusterConfiguration/operators/OperatorCheckbox.d.ts.map +1 -1
- package/build/@types/ocm/components/clusterWizard/OperatorsBundle.d.ts +2 -1
- package/build/@types/ocm/components/clusterWizard/OperatorsBundle.d.ts.map +1 -1
- package/build/@types/ocm/components/clusterWizard/OperatorsSelect.d.ts +2 -1
- package/build/@types/ocm/components/clusterWizard/OperatorsSelect.d.ts.map +1 -1
- package/build/@types/ocm/components/clusterWizard/OperatorsStep.d.ts.map +1 -1
- package/build/cjs/common/components/operators/operatorSpecs.js +111 -139
- package/build/cjs/common/components/operators/operatorSpecs.js.map +1 -1
- package/build/cjs/common/components/operators/test.js +323 -0
- package/build/cjs/common/components/operators/test.js.map +1 -0
- package/build/cjs/ocm/components/clusterConfiguration/ControlPlaneNodesDropdown.js +13 -4
- package/build/cjs/ocm/components/clusterConfiguration/ControlPlaneNodesDropdown.js.map +1 -1
- package/build/cjs/ocm/components/clusterConfiguration/operators/OperatorCheckbox.js +3 -3
- package/build/cjs/ocm/components/clusterConfiguration/operators/OperatorCheckbox.js.map +1 -1
- package/build/cjs/ocm/components/clusterWizard/OperatorsBundle.js +8 -8
- package/build/cjs/ocm/components/clusterWizard/OperatorsBundle.js.map +1 -1
- package/build/cjs/ocm/components/clusterWizard/OperatorsSelect.js +33 -14
- package/build/cjs/ocm/components/clusterWizard/OperatorsSelect.js.map +1 -1
- package/build/cjs/ocm/components/clusterWizard/OperatorsStep.js +13 -3
- package/build/cjs/ocm/components/clusterWizard/OperatorsStep.js.map +1 -1
- package/lib/common/components/operators/operatorSpecs.tsx +123 -160
- package/lib/common/components/operators/test.tsx +469 -0
- package/lib/ocm/components/clusterConfiguration/ControlPlaneNodesDropdown.tsx +21 -9
- package/lib/ocm/components/clusterConfiguration/operators/OperatorCheckbox.tsx +5 -2
- package/lib/ocm/components/clusterWizard/OperatorsBundle.tsx +15 -7
- package/lib/ocm/components/clusterWizard/OperatorsSelect.tsx +58 -37
- package/lib/ocm/components/clusterWizard/OperatorsStep.tsx +30 -3
- package/package.json +3 -3
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Cluster, SupportLevel } from '@openshift-assisted/types/assisted-installer-service';
|
|
3
|
+
import { FeatureId } from '../../types';
|
|
4
|
+
import {
|
|
5
|
+
OPERATOR_NAME_AMD_GPU,
|
|
6
|
+
OPERATOR_NAME_AUTHORINO,
|
|
7
|
+
OPERATOR_NAME_CNV,
|
|
8
|
+
OPERATOR_NAME_KMM,
|
|
9
|
+
OPERATOR_NAME_LSO,
|
|
10
|
+
OPERATOR_NAME_LVM,
|
|
11
|
+
OPERATOR_NAME_MCE,
|
|
12
|
+
OPERATOR_NAME_MTV,
|
|
13
|
+
OPERATOR_NAME_NMSTATE,
|
|
14
|
+
OPERATOR_NAME_NODE_FEATURE_DISCOVERY,
|
|
15
|
+
OPERATOR_NAME_NVIDIA_GPU,
|
|
16
|
+
OPERATOR_NAME_ODF,
|
|
17
|
+
OPERATOR_NAME_OPENSHIFT_AI,
|
|
18
|
+
OPERATOR_NAME_OSC,
|
|
19
|
+
OPERATOR_NAME_PIPELINES,
|
|
20
|
+
OPERATOR_NAME_SERVERLESS,
|
|
21
|
+
OPERATOR_NAME_SERVICEMESH,
|
|
22
|
+
OPERATOR_NAME_NODE_MAINTENANCE,
|
|
23
|
+
OPERATOR_NAME_KUBE_DESCHEDULER,
|
|
24
|
+
} from '../../config/constants';
|
|
25
|
+
import { ExternalLink } from '../ui';
|
|
26
|
+
import {
|
|
27
|
+
AUTHORINO_OPERATOR_LINK,
|
|
28
|
+
CNV_LINK,
|
|
29
|
+
getKmmDocsLink,
|
|
30
|
+
getKubeDeschedulerLink,
|
|
31
|
+
getLsoLink,
|
|
32
|
+
getLvmsDocsLink,
|
|
33
|
+
getMceDocsLink,
|
|
34
|
+
getNmstateLink,
|
|
35
|
+
getNodeFeatureDiscoveryLink,
|
|
36
|
+
getNvidiaGpuLink,
|
|
37
|
+
getServiceMeshLink,
|
|
38
|
+
MTV_LINK,
|
|
39
|
+
NODE_MAINTENANCE_LINK,
|
|
40
|
+
ODF_LINK,
|
|
41
|
+
ODF_REQUIREMENTS_LINK,
|
|
42
|
+
OPENSHIFT_AI_LINK,
|
|
43
|
+
OPENSHIFT_AI_REQUIREMENTS_LINK,
|
|
44
|
+
OSC_LINK,
|
|
45
|
+
OSC_REQUIREMENTS_LINK,
|
|
46
|
+
PIPELINES_OPERATOR_LINK,
|
|
47
|
+
SERVERLESS_OPERATOR_LINK,
|
|
48
|
+
} from '../../config';
|
|
49
|
+
import { getMajorMinorVersion } from '../../utils';
|
|
50
|
+
import { GetFeatureSupportLevel, useNewFeatureSupportLevel } from '../newFeatureSupportLevels';
|
|
51
|
+
import {
|
|
52
|
+
DESCRIPTION_AMD_GPU,
|
|
53
|
+
DESCRIPTION_AUTHORINO,
|
|
54
|
+
DESCRIPTION_LSO,
|
|
55
|
+
DESCRIPTION_MTV,
|
|
56
|
+
DESCRIPTION_CNV,
|
|
57
|
+
DESCRIPTION_KMM,
|
|
58
|
+
DESCRIPTION_KUBE_DESCHEDULER,
|
|
59
|
+
DESCRIPTION_MCE,
|
|
60
|
+
DESCRIPTION_NMSTATE,
|
|
61
|
+
DESCRIPTION_NODE_FEATURE_DISCOVERY,
|
|
62
|
+
DESCRIPTION_NODE_MAINTENANCE,
|
|
63
|
+
DESCRIPTION_NVIDIA_GPU,
|
|
64
|
+
DESCRIPTION_ODF,
|
|
65
|
+
DESCRIPTION_OPENSHIFT_AI,
|
|
66
|
+
DESCRIPTION_OSC,
|
|
67
|
+
DESCRIPTION_PIPELINES,
|
|
68
|
+
DESCRIPTION_SERVERLESS,
|
|
69
|
+
DESCRIPTION_SERVICEMESH,
|
|
70
|
+
DESCRIPTION_LVM,
|
|
71
|
+
} from './operatorDescriptions';
|
|
72
|
+
|
|
73
|
+
// TODO check if it's unused and it can be deleted in favor of "isMajorMinorVersionEqualOrGreater"
|
|
74
|
+
export const isOCPVersionEqualsOrMore = (
|
|
75
|
+
openshiftVersion: string,
|
|
76
|
+
ocpVersionToCompare: string,
|
|
77
|
+
): boolean => {
|
|
78
|
+
const [majorA, minorA] = getMajorMinorVersion(openshiftVersion).split('.');
|
|
79
|
+
const [majorB, minorB] = ocpVersionToCompare.split('.');
|
|
80
|
+
return (
|
|
81
|
+
Number(majorA) > Number(majorB) ||
|
|
82
|
+
(Number(majorA) === Number(majorB) && Number(minorA) >= Number(minorB))
|
|
83
|
+
);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export const highlightMatch = (text: string, searchTerm?: string): React.ReactNode => {
|
|
87
|
+
if (!searchTerm) return text;
|
|
88
|
+
const escapeSearchTerm = searchTerm.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
89
|
+
const regex = new RegExp(`(${escapeSearchTerm})`, 'gi');
|
|
90
|
+
|
|
91
|
+
const parts = text.split(regex);
|
|
92
|
+
|
|
93
|
+
return parts.map((part, i) =>
|
|
94
|
+
part.toLowerCase() === searchTerm.toLowerCase() ? <mark key={i}>{part}</mark> : part,
|
|
95
|
+
);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export const HighlightedText = ({ text, searchTerm }: { text: string; searchTerm?: string }) => (
|
|
99
|
+
<>{highlightMatch(text, searchTerm)}</>
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
export type OperatorSpec = {
|
|
103
|
+
operatorKey: string;
|
|
104
|
+
title: string;
|
|
105
|
+
featureId: FeatureId;
|
|
106
|
+
descriptionText?: string;
|
|
107
|
+
Description?: React.ComponentType<{ openshiftVersion?: string; searchTerm?: string }>;
|
|
108
|
+
notStandalone?: boolean;
|
|
109
|
+
Requirements?: React.ComponentType<{ cluster: Cluster }>;
|
|
110
|
+
supportLevel?: SupportLevel | undefined;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export const getOperatorSpecs = (
|
|
114
|
+
getFeatureSupportLevel: GetFeatureSupportLevel,
|
|
115
|
+
useLVMS?: boolean,
|
|
116
|
+
): { [category: string]: OperatorSpec[] } => {
|
|
117
|
+
return {
|
|
118
|
+
[categories[Category.STORAGE]]: [
|
|
119
|
+
{
|
|
120
|
+
operatorKey: OPERATOR_NAME_LSO,
|
|
121
|
+
title: 'Local Storage Operator',
|
|
122
|
+
featureId: 'LSO',
|
|
123
|
+
descriptionText: DESCRIPTION_LSO,
|
|
124
|
+
Description: ({ openshiftVersion, searchTerm }) => (
|
|
125
|
+
<>
|
|
126
|
+
<HighlightedText text={DESCRIPTION_LSO} searchTerm={searchTerm} />{' '}
|
|
127
|
+
<ExternalLink href={getLsoLink(openshiftVersion)}>Learn more</ExternalLink>
|
|
128
|
+
</>
|
|
129
|
+
),
|
|
130
|
+
notStandalone: true,
|
|
131
|
+
supportLevel: getFeatureSupportLevel('LSO'),
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
operatorKey: OPERATOR_NAME_LVM,
|
|
135
|
+
title: useLVMS ? 'Logical Volume Manager Storage' : 'Logical Volume Manager',
|
|
136
|
+
featureId: 'LVM',
|
|
137
|
+
descriptionText: DESCRIPTION_LVM,
|
|
138
|
+
Description: ({ openshiftVersion, searchTerm }) =>
|
|
139
|
+
useLVMS ? (
|
|
140
|
+
<>
|
|
141
|
+
<HighlightedText text={DESCRIPTION_LVM} searchTerm={searchTerm} />{' '}
|
|
142
|
+
<ExternalLink href={getLvmsDocsLink(openshiftVersion)}>Learn more</ExternalLink>
|
|
143
|
+
</>
|
|
144
|
+
) : (
|
|
145
|
+
<>{DESCRIPTION_LVM}</>
|
|
146
|
+
),
|
|
147
|
+
supportLevel: getFeatureSupportLevel('LVM'),
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
operatorKey: OPERATOR_NAME_ODF,
|
|
151
|
+
title: 'OpenShift Data Foundation',
|
|
152
|
+
featureId: 'ODF',
|
|
153
|
+
descriptionText: DESCRIPTION_ODF,
|
|
154
|
+
Requirements: () => (
|
|
155
|
+
<ExternalLink href={ODF_REQUIREMENTS_LINK}>
|
|
156
|
+
Learn more about the requirements for OpenShift Data Foundation
|
|
157
|
+
</ExternalLink>
|
|
158
|
+
),
|
|
159
|
+
Description: ({ searchTerm }) => (
|
|
160
|
+
<>
|
|
161
|
+
<HighlightedText text={DESCRIPTION_ODF} searchTerm={searchTerm} />{' '}
|
|
162
|
+
<ExternalLink href={ODF_LINK}>Learn more</ExternalLink>
|
|
163
|
+
</>
|
|
164
|
+
),
|
|
165
|
+
supportLevel: getFeatureSupportLevel('ODF'),
|
|
166
|
+
},
|
|
167
|
+
],
|
|
168
|
+
[categories[Category.VIRT]]: [
|
|
169
|
+
{
|
|
170
|
+
operatorKey: OPERATOR_NAME_CNV,
|
|
171
|
+
title: 'OpenShift Virtualization',
|
|
172
|
+
featureId: 'CNV',
|
|
173
|
+
descriptionText: DESCRIPTION_CNV,
|
|
174
|
+
Requirements: () => (
|
|
175
|
+
<>Enabled CPU virtualization support in BIOS (Intel-VT / AMD-V) on all nodes</>
|
|
176
|
+
),
|
|
177
|
+
Description: ({ searchTerm }) => (
|
|
178
|
+
<>
|
|
179
|
+
<HighlightedText text={DESCRIPTION_CNV} searchTerm={searchTerm} />{' '}
|
|
180
|
+
<ExternalLink href={CNV_LINK}>Learn more</ExternalLink>
|
|
181
|
+
</>
|
|
182
|
+
),
|
|
183
|
+
supportLevel: getFeatureSupportLevel('CNV'),
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
operatorKey: OPERATOR_NAME_MTV,
|
|
187
|
+
title: 'Migration Toolkit for Virtualization',
|
|
188
|
+
featureId: 'MTV',
|
|
189
|
+
descriptionText: DESCRIPTION_MTV,
|
|
190
|
+
Description: ({ searchTerm }) => (
|
|
191
|
+
<>
|
|
192
|
+
<HighlightedText text={DESCRIPTION_MTV} searchTerm={searchTerm} />{' '}
|
|
193
|
+
<ExternalLink href={MTV_LINK}>Learn more</ExternalLink>
|
|
194
|
+
</>
|
|
195
|
+
),
|
|
196
|
+
supportLevel: getFeatureSupportLevel('MTV'),
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
operatorKey: OPERATOR_NAME_OSC,
|
|
200
|
+
title: 'OpenShift sandboxed containers',
|
|
201
|
+
featureId: 'OSC',
|
|
202
|
+
descriptionText: DESCRIPTION_OSC,
|
|
203
|
+
Requirements: () => (
|
|
204
|
+
<ExternalLink href={OSC_REQUIREMENTS_LINK}>
|
|
205
|
+
Learn more about the requirements for OpenShift sandboxed containers
|
|
206
|
+
</ExternalLink>
|
|
207
|
+
),
|
|
208
|
+
Description: () => (
|
|
209
|
+
<>
|
|
210
|
+
{DESCRIPTION_OSC} <ExternalLink href={OSC_LINK}>Learn more</ExternalLink>
|
|
211
|
+
</>
|
|
212
|
+
),
|
|
213
|
+
supportLevel: getFeatureSupportLevel('OSC'),
|
|
214
|
+
},
|
|
215
|
+
],
|
|
216
|
+
[categories[Category.AI]]: [
|
|
217
|
+
{
|
|
218
|
+
operatorKey: OPERATOR_NAME_OPENSHIFT_AI,
|
|
219
|
+
title: 'OpenShift AI',
|
|
220
|
+
featureId: 'OPENSHIFT_AI',
|
|
221
|
+
descriptionText: DESCRIPTION_OPENSHIFT_AI,
|
|
222
|
+
Requirements: () => (
|
|
223
|
+
<ExternalLink href={OPENSHIFT_AI_REQUIREMENTS_LINK}>Learn more</ExternalLink>
|
|
224
|
+
),
|
|
225
|
+
Description: ({ searchTerm }) => (
|
|
226
|
+
<>
|
|
227
|
+
<HighlightedText text={DESCRIPTION_OPENSHIFT_AI} searchTerm={searchTerm} />{' '}
|
|
228
|
+
<ExternalLink href={OPENSHIFT_AI_LINK}>Learn more</ExternalLink>
|
|
229
|
+
</>
|
|
230
|
+
),
|
|
231
|
+
supportLevel: getFeatureSupportLevel('OPENSHIFT_AI'),
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
operatorKey: OPERATOR_NAME_AMD_GPU,
|
|
235
|
+
title: 'AMD GPU',
|
|
236
|
+
featureId: 'AMD_GPU',
|
|
237
|
+
descriptionText: DESCRIPTION_AMD_GPU,
|
|
238
|
+
Requirements: () => <>Requires at least one supported AMD GPU</>,
|
|
239
|
+
Description: ({ searchTerm }) => (
|
|
240
|
+
<>
|
|
241
|
+
{' '}
|
|
242
|
+
<HighlightedText text={DESCRIPTION_AMD_GPU} searchTerm={searchTerm} />{' '}
|
|
243
|
+
</>
|
|
244
|
+
),
|
|
245
|
+
supportLevel: getFeatureSupportLevel('AMD_GPU'),
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
operatorKey: OPERATOR_NAME_NVIDIA_GPU,
|
|
249
|
+
title: 'NVIDIA GPU',
|
|
250
|
+
featureId: 'NVIDIA_GPU',
|
|
251
|
+
descriptionText: DESCRIPTION_NVIDIA_GPU,
|
|
252
|
+
Requirements: () => <>Requires at least one supported NVIDIA GPU</>,
|
|
253
|
+
Description: ({ openshiftVersion, searchTerm }) => (
|
|
254
|
+
<>
|
|
255
|
+
<HighlightedText text={DESCRIPTION_NVIDIA_GPU} searchTerm={searchTerm} />{' '}
|
|
256
|
+
<ExternalLink href={getNvidiaGpuLink(openshiftVersion)}>Learn more</ExternalLink>
|
|
257
|
+
</>
|
|
258
|
+
),
|
|
259
|
+
supportLevel: getFeatureSupportLevel('NVIDIA_GPU'),
|
|
260
|
+
},
|
|
261
|
+
],
|
|
262
|
+
[categories[Category.NETWORK]]: [
|
|
263
|
+
{
|
|
264
|
+
operatorKey: OPERATOR_NAME_NMSTATE,
|
|
265
|
+
title: 'NMState',
|
|
266
|
+
featureId: 'NMSTATE',
|
|
267
|
+
descriptionText: DESCRIPTION_NMSTATE,
|
|
268
|
+
Description: ({ openshiftVersion, searchTerm }) => (
|
|
269
|
+
<>
|
|
270
|
+
<HighlightedText text={DESCRIPTION_NMSTATE} searchTerm={searchTerm} />{' '}
|
|
271
|
+
<ExternalLink href={getNmstateLink(openshiftVersion)}>Learn more</ExternalLink>
|
|
272
|
+
</>
|
|
273
|
+
),
|
|
274
|
+
supportLevel: getFeatureSupportLevel('NMSTATE'),
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
operatorKey: OPERATOR_NAME_SERVICEMESH,
|
|
278
|
+
title: 'Service Mesh',
|
|
279
|
+
featureId: 'SERVICEMESH',
|
|
280
|
+
descriptionText: DESCRIPTION_SERVICEMESH,
|
|
281
|
+
Description: ({ openshiftVersion, searchTerm }) => (
|
|
282
|
+
<>
|
|
283
|
+
<HighlightedText text={DESCRIPTION_SERVICEMESH} searchTerm={searchTerm} />{' '}
|
|
284
|
+
<ExternalLink href={getServiceMeshLink(openshiftVersion)}>Learn more</ExternalLink>
|
|
285
|
+
</>
|
|
286
|
+
),
|
|
287
|
+
notStandalone: true,
|
|
288
|
+
supportLevel: getFeatureSupportLevel('SERVICEMESH'),
|
|
289
|
+
},
|
|
290
|
+
],
|
|
291
|
+
[categories[Category.SECURITY]]: [
|
|
292
|
+
{
|
|
293
|
+
operatorKey: OPERATOR_NAME_AUTHORINO,
|
|
294
|
+
title: 'Authorino',
|
|
295
|
+
featureId: 'AUTHORINO',
|
|
296
|
+
descriptionText: DESCRIPTION_AUTHORINO,
|
|
297
|
+
Description: ({ searchTerm }) => (
|
|
298
|
+
<>
|
|
299
|
+
<HighlightedText text={DESCRIPTION_AUTHORINO} searchTerm={searchTerm} />{' '}
|
|
300
|
+
<ExternalLink href={AUTHORINO_OPERATOR_LINK}>Learn more</ExternalLink>
|
|
301
|
+
</>
|
|
302
|
+
),
|
|
303
|
+
notStandalone: true,
|
|
304
|
+
supportLevel: getFeatureSupportLevel('AUTHORINO'),
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
operatorKey: OPERATOR_NAME_KMM,
|
|
308
|
+
title: 'Kernel Module Management',
|
|
309
|
+
featureId: 'KMM',
|
|
310
|
+
descriptionText: DESCRIPTION_KMM,
|
|
311
|
+
Description: ({ openshiftVersion, searchTerm }) => (
|
|
312
|
+
<>
|
|
313
|
+
<HighlightedText text={DESCRIPTION_KMM} searchTerm={searchTerm} />{' '}
|
|
314
|
+
<ExternalLink href={getKmmDocsLink(openshiftVersion)}>Learn more</ExternalLink>
|
|
315
|
+
</>
|
|
316
|
+
),
|
|
317
|
+
supportLevel: getFeatureSupportLevel('KMM'),
|
|
318
|
+
},
|
|
319
|
+
],
|
|
320
|
+
[categories[Category.CI_CD]]: [
|
|
321
|
+
{
|
|
322
|
+
operatorKey: OPERATOR_NAME_PIPELINES,
|
|
323
|
+
title: 'Pipelines',
|
|
324
|
+
featureId: 'PIPELINES',
|
|
325
|
+
descriptionText: DESCRIPTION_PIPELINES,
|
|
326
|
+
Description: ({ searchTerm }) => (
|
|
327
|
+
<>
|
|
328
|
+
<HighlightedText text={DESCRIPTION_PIPELINES} searchTerm={searchTerm} />{' '}
|
|
329
|
+
<ExternalLink href={PIPELINES_OPERATOR_LINK}>Learn more</ExternalLink>
|
|
330
|
+
</>
|
|
331
|
+
),
|
|
332
|
+
notStandalone: true,
|
|
333
|
+
supportLevel: getFeatureSupportLevel('PIPELINES'),
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
operatorKey: OPERATOR_NAME_SERVERLESS,
|
|
337
|
+
title: 'Serverless',
|
|
338
|
+
featureId: 'SERVERLESS',
|
|
339
|
+
descriptionText: DESCRIPTION_SERVERLESS,
|
|
340
|
+
Description: ({ searchTerm }) => (
|
|
341
|
+
<>
|
|
342
|
+
<HighlightedText text={DESCRIPTION_SERVERLESS} searchTerm={searchTerm} />{' '}
|
|
343
|
+
<ExternalLink href={SERVERLESS_OPERATOR_LINK}>Learn more</ExternalLink>
|
|
344
|
+
</>
|
|
345
|
+
),
|
|
346
|
+
notStandalone: true,
|
|
347
|
+
supportLevel: getFeatureSupportLevel('SERVERLESS'),
|
|
348
|
+
},
|
|
349
|
+
],
|
|
350
|
+
[categories[Category.PLATFORM]]: [
|
|
351
|
+
{
|
|
352
|
+
operatorKey: OPERATOR_NAME_MCE,
|
|
353
|
+
title: 'Multicluster engine',
|
|
354
|
+
featureId: 'MCE',
|
|
355
|
+
descriptionText: DESCRIPTION_MCE,
|
|
356
|
+
Description: ({ openshiftVersion, searchTerm }) => (
|
|
357
|
+
<>
|
|
358
|
+
<HighlightedText text={DESCRIPTION_MCE} searchTerm={searchTerm} />{' '}
|
|
359
|
+
<ExternalLink href={getMceDocsLink(openshiftVersion)}>Learn more</ExternalLink>
|
|
360
|
+
</>
|
|
361
|
+
),
|
|
362
|
+
supportLevel: getFeatureSupportLevel('MCE'),
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
operatorKey: OPERATOR_NAME_NODE_MAINTENANCE,
|
|
366
|
+
title: 'Node Maintenance',
|
|
367
|
+
featureId: 'NODE_MAINTENANCE',
|
|
368
|
+
descriptionText: DESCRIPTION_NODE_MAINTENANCE,
|
|
369
|
+
Description: () => (
|
|
370
|
+
<>
|
|
371
|
+
{DESCRIPTION_NODE_MAINTENANCE}{' '}
|
|
372
|
+
<ExternalLink href={NODE_MAINTENANCE_LINK}>Learn more</ExternalLink>
|
|
373
|
+
</>
|
|
374
|
+
),
|
|
375
|
+
notStandalone: true,
|
|
376
|
+
supportLevel: getFeatureSupportLevel('NODE_MAINTENANCE'),
|
|
377
|
+
},
|
|
378
|
+
],
|
|
379
|
+
[categories[Category.SCHEDULING]]: [
|
|
380
|
+
{
|
|
381
|
+
operatorKey: OPERATOR_NAME_NODE_FEATURE_DISCOVERY,
|
|
382
|
+
title: 'Node Feature Discovery',
|
|
383
|
+
featureId: 'NODE_FEATURE_DISCOVERY',
|
|
384
|
+
descriptionText: DESCRIPTION_NODE_FEATURE_DISCOVERY,
|
|
385
|
+
Description: ({ openshiftVersion }) => (
|
|
386
|
+
<>
|
|
387
|
+
{DESCRIPTION_NODE_FEATURE_DISCOVERY}{' '}
|
|
388
|
+
<ExternalLink href={getNodeFeatureDiscoveryLink(openshiftVersion)}>
|
|
389
|
+
Learn more
|
|
390
|
+
</ExternalLink>
|
|
391
|
+
</>
|
|
392
|
+
),
|
|
393
|
+
supportLevel: getFeatureSupportLevel('NODE_FEATURE_DISCOVERY'),
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
operatorKey: OPERATOR_NAME_KUBE_DESCHEDULER,
|
|
397
|
+
title: 'Kube Descheduler',
|
|
398
|
+
featureId: 'KUBE_DESCHEDULER',
|
|
399
|
+
descriptionText: DESCRIPTION_KUBE_DESCHEDULER,
|
|
400
|
+
Description: ({ openshiftVersion, searchTerm }) => (
|
|
401
|
+
<>
|
|
402
|
+
<HighlightedText text={DESCRIPTION_KUBE_DESCHEDULER} searchTerm={searchTerm} />{' '}
|
|
403
|
+
<ExternalLink href={getKubeDeschedulerLink(openshiftVersion)}>Learn more</ExternalLink>
|
|
404
|
+
</>
|
|
405
|
+
),
|
|
406
|
+
notStandalone: true,
|
|
407
|
+
supportLevel: getFeatureSupportLevel('KUBE_DESCHEDULER'),
|
|
408
|
+
},
|
|
409
|
+
],
|
|
410
|
+
};
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
export const useOperatorSpecs = () => {
|
|
414
|
+
const { getFeatureSupportLevel } = useNewFeatureSupportLevel();
|
|
415
|
+
const useLVMS = getFeatureSupportLevel('LVM') === 'supported';
|
|
416
|
+
|
|
417
|
+
// Grouped by category
|
|
418
|
+
const byCategory = React.useMemo(
|
|
419
|
+
() => getOperatorSpecs(getFeatureSupportLevel, useLVMS),
|
|
420
|
+
[getFeatureSupportLevel, useLVMS],
|
|
421
|
+
);
|
|
422
|
+
|
|
423
|
+
// Flat map operatorKey -> spec
|
|
424
|
+
const byKey: Record<string, OperatorSpec> = React.useMemo(() => {
|
|
425
|
+
return Object.values(byCategory).reduce((acc, specs) => {
|
|
426
|
+
specs.forEach((spec) => {
|
|
427
|
+
acc[spec.operatorKey] = spec;
|
|
428
|
+
});
|
|
429
|
+
return acc;
|
|
430
|
+
}, {} as Record<string, OperatorSpec>);
|
|
431
|
+
}, [byCategory]);
|
|
432
|
+
|
|
433
|
+
return { byCategory, byKey };
|
|
434
|
+
};
|
|
435
|
+
|
|
436
|
+
export const getOperatorTitleByFeatureId = (featureId: FeatureId): string | undefined => {
|
|
437
|
+
const allSpecs = getOperatorSpecs(() => undefined);
|
|
438
|
+
|
|
439
|
+
for (const categorySpecs of Object.values(allSpecs)) {
|
|
440
|
+
const spec = categorySpecs.find((s) => s.featureId === featureId);
|
|
441
|
+
if (spec) {
|
|
442
|
+
return spec.title;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
return undefined;
|
|
447
|
+
};
|
|
448
|
+
|
|
449
|
+
enum Category {
|
|
450
|
+
STORAGE,
|
|
451
|
+
VIRT,
|
|
452
|
+
AI,
|
|
453
|
+
NETWORK,
|
|
454
|
+
CI_CD,
|
|
455
|
+
PLATFORM,
|
|
456
|
+
SECURITY,
|
|
457
|
+
SCHEDULING,
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
export const categories: { [key in Category]: string } = {
|
|
461
|
+
[Category.STORAGE]: 'Storage',
|
|
462
|
+
[Category.VIRT]: 'Virtualization',
|
|
463
|
+
[Category.AI]: 'AI',
|
|
464
|
+
[Category.NETWORK]: 'Network',
|
|
465
|
+
[Category.SECURITY]: 'Security & Access Control',
|
|
466
|
+
[Category.CI_CD]: 'CI/CD & Dev Productivity',
|
|
467
|
+
[Category.PLATFORM]: 'Platform Operations & Lifecycle',
|
|
468
|
+
[Category.SCHEDULING]: 'Scheduling',
|
|
469
|
+
};
|
|
@@ -9,11 +9,12 @@ import {
|
|
|
9
9
|
DropdownList,
|
|
10
10
|
} from '@patternfly/react-core';
|
|
11
11
|
import { useField } from 'formik';
|
|
12
|
-
import { getFieldId, PopoverIcon } from '../../../common';
|
|
12
|
+
import { getFieldId, PopoverIcon, PreviewBadgePosition, TechnologyPreview } from '../../../common';
|
|
13
13
|
import {
|
|
14
14
|
NewFeatureSupportLevelMap,
|
|
15
15
|
useNewFeatureSupportLevel,
|
|
16
16
|
} from '../../../common/components/newFeatureSupportLevels';
|
|
17
|
+
import { isFeatureSupportedAndAvailable } from '../featureSupportLevels/featureStateUtils';
|
|
17
18
|
import OcmTNADisclaimer from './OcmTNADisclaimer';
|
|
18
19
|
import toNumber from 'lodash-es/toNumber';
|
|
19
20
|
import OcmSNODisclaimer from './OcmSNODisclaimer';
|
|
@@ -42,6 +43,7 @@ export const ControlPlaneNodesLabel = () => {
|
|
|
42
43
|
interface ControlPlaneNodesOption {
|
|
43
44
|
value: number;
|
|
44
45
|
label: string;
|
|
46
|
+
badge?: React.ReactNode;
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
interface ControlPlaneNodesDropdownProps {
|
|
@@ -90,19 +92,27 @@ const ControlPlaneNodesDropdown: React.FC<ControlPlaneNodesDropdownProps> = ({
|
|
|
90
92
|
featureSupportLevelData ?? undefined,
|
|
91
93
|
);
|
|
92
94
|
|
|
95
|
+
const tnaSupport = newFeatureSupportLevelContext.getFeatureSupportLevel(
|
|
96
|
+
'TNA',
|
|
97
|
+
featureSupportLevelData ?? undefined,
|
|
98
|
+
);
|
|
99
|
+
const isTnaEnabled = isFeatureSupportedAndAvailable(tnaSupport || 'unsupported');
|
|
100
|
+
|
|
93
101
|
const options: ControlPlaneNodesOption[] = [
|
|
94
102
|
{ value: 1, label: '1 (Single Node OpenShift)' },
|
|
95
|
-
{
|
|
103
|
+
{
|
|
104
|
+
value: 2,
|
|
105
|
+
label: '2 (Two-Nodes Arbiter)',
|
|
106
|
+
badge:
|
|
107
|
+
tnaSupport === 'tech-preview' ? (
|
|
108
|
+
<TechnologyPreview position={PreviewBadgePosition.default} />
|
|
109
|
+
) : undefined,
|
|
110
|
+
},
|
|
96
111
|
{ value: 3, label: '3 (highly available cluster)' },
|
|
97
112
|
{ value: 4, label: '4 (highly available cluster+)' },
|
|
98
113
|
{ value: 5, label: '5 (highly available cluster++)' },
|
|
99
114
|
];
|
|
100
115
|
|
|
101
|
-
const isTnaEnabled = newFeatureSupportLevelContext.isFeatureSupported(
|
|
102
|
-
'TNA',
|
|
103
|
-
featureSupportLevelData ?? undefined,
|
|
104
|
-
);
|
|
105
|
-
|
|
106
116
|
React.useEffect(() => {
|
|
107
117
|
if (!field.value) {
|
|
108
118
|
setValue(DEFAULT_VALUE_CPN);
|
|
@@ -115,7 +125,7 @@ const ControlPlaneNodesDropdown: React.FC<ControlPlaneNodesDropdownProps> = ({
|
|
|
115
125
|
setOpen(false);
|
|
116
126
|
};
|
|
117
127
|
|
|
118
|
-
const dropdownItems = options.map(({ value, label }) => {
|
|
128
|
+
const dropdownItems = options.map(({ value, label, badge }) => {
|
|
119
129
|
const isItemEnabled = isCPNDropdownItemEnabled(
|
|
120
130
|
value,
|
|
121
131
|
isNonStandardControlPlaneEnabled,
|
|
@@ -124,7 +134,9 @@ const ControlPlaneNodesDropdown: React.FC<ControlPlaneNodesDropdownProps> = ({
|
|
|
124
134
|
return (
|
|
125
135
|
<DropdownItem key={value} id={value.toString()} isAriaDisabled={!isItemEnabled}>
|
|
126
136
|
<Tooltip hidden={isItemEnabled} content={disabledReason} position="top">
|
|
127
|
-
<div>
|
|
137
|
+
<div>
|
|
138
|
+
{label} {badge}
|
|
139
|
+
</div>
|
|
128
140
|
</Tooltip>
|
|
129
141
|
</DropdownItem>
|
|
130
142
|
);
|
|
@@ -26,6 +26,7 @@ import { getFieldId, OperatorsValues, PopoverIcon } from '../../../../common';
|
|
|
26
26
|
import { useNewFeatureSupportLevel } from '../../../../common/components/newFeatureSupportLevels';
|
|
27
27
|
import { getNewOperators } from './utils';
|
|
28
28
|
import {
|
|
29
|
+
highlightMatch,
|
|
29
30
|
OperatorSpec,
|
|
30
31
|
useOperatorSpecs,
|
|
31
32
|
} from '../../../../common/components/operators/operatorSpecs';
|
|
@@ -118,12 +119,14 @@ const OperatorCheckbox = ({
|
|
|
118
119
|
Requirements,
|
|
119
120
|
openshiftVersion,
|
|
120
121
|
preflightRequirements,
|
|
122
|
+
searchTerm,
|
|
121
123
|
}: {
|
|
122
124
|
bundles: Bundle[];
|
|
123
125
|
cluster: Cluster;
|
|
124
126
|
operatorId: string;
|
|
125
127
|
openshiftVersion?: string;
|
|
126
128
|
preflightRequirements: PreflightHardwareRequirements | undefined;
|
|
129
|
+
searchTerm?: string;
|
|
127
130
|
} & OperatorSpec) => {
|
|
128
131
|
const { getFeatureSupportLevel, getFeatureDisabledReason } = useNewFeatureSupportLevel();
|
|
129
132
|
const { byKey: opSpecs } = useOperatorSpecs();
|
|
@@ -166,7 +169,7 @@ const OperatorCheckbox = ({
|
|
|
166
169
|
label={
|
|
167
170
|
<>
|
|
168
171
|
<Tooltip hidden={!disabledReason} content={disabledReason}>
|
|
169
|
-
<span>{title} </span>
|
|
172
|
+
<span>{highlightMatch(title, searchTerm)} </span>
|
|
170
173
|
</Tooltip>
|
|
171
174
|
<OperatorRequirements
|
|
172
175
|
operatorId={operatorId}
|
|
@@ -196,7 +199,7 @@ const OperatorCheckbox = ({
|
|
|
196
199
|
!!Description && (
|
|
197
200
|
<HelperText>
|
|
198
201
|
<HelperTextItem variant="indeterminate">
|
|
199
|
-
<Description openshiftVersion={openshiftVersion} />
|
|
202
|
+
<Description openshiftVersion={openshiftVersion} searchTerm={searchTerm} />
|
|
200
203
|
</HelperTextItem>
|
|
201
204
|
</HelperText>
|
|
202
205
|
)
|
|
@@ -30,17 +30,20 @@ import { useSelector } from 'react-redux';
|
|
|
30
30
|
import { selectIsCurrentClusterSNO } from '../../store/slices/current-cluster/selectors';
|
|
31
31
|
import { getNewBundleOperators } from '../clusterConfiguration/operators/utils';
|
|
32
32
|
import { bundleSpecs } from '../clusterConfiguration/operators/bundleSpecs';
|
|
33
|
-
import {
|
|
33
|
+
import {
|
|
34
|
+
highlightMatch,
|
|
35
|
+
OperatorSpec,
|
|
36
|
+
useOperatorSpecs,
|
|
37
|
+
} from '../../../common/components/operators/operatorSpecs';
|
|
34
38
|
import { useClusterWizardContext } from './ClusterWizardContext';
|
|
35
39
|
import './OperatorsBundle.css';
|
|
36
40
|
|
|
37
|
-
const BundleLabel = ({ bundle }: { bundle: Bundle }) => {
|
|
41
|
+
const BundleLabel = ({ bundle, searchTerm }: { bundle: Bundle; searchTerm?: string }) => {
|
|
38
42
|
const { byKey: opSpecs } = useOperatorSpecs();
|
|
39
43
|
const bundleSpec = bundleSpecs[bundle.id || ''];
|
|
40
|
-
|
|
41
44
|
return (
|
|
42
45
|
<>
|
|
43
|
-
<span>{bundle.title} </span>
|
|
46
|
+
<span>{highlightMatch(bundle.title || '', searchTerm)} </span>
|
|
44
47
|
<PopoverIcon
|
|
45
48
|
component={'a'}
|
|
46
49
|
headerContent={<div>Requirements and dependencies</div>}
|
|
@@ -100,10 +103,12 @@ const BundleCard = ({
|
|
|
100
103
|
bundle,
|
|
101
104
|
bundles,
|
|
102
105
|
preflightRequirements,
|
|
106
|
+
searchTerm,
|
|
103
107
|
}: {
|
|
104
108
|
bundle: Bundle;
|
|
105
109
|
bundles: Bundle[];
|
|
106
110
|
preflightRequirements: PreflightHardwareRequirements | undefined;
|
|
111
|
+
searchTerm?: string;
|
|
107
112
|
}) => {
|
|
108
113
|
const { values, setFieldValue } = useFormikContext<OperatorsValues>();
|
|
109
114
|
const isSNO = useSelector(selectIsCurrentClusterSNO);
|
|
@@ -177,13 +182,13 @@ const BundleCard = ({
|
|
|
177
182
|
}}
|
|
178
183
|
>
|
|
179
184
|
<CardTitle>
|
|
180
|
-
<BundleLabel bundle={bundle} />
|
|
185
|
+
<BundleLabel bundle={bundle} searchTerm={searchTerm} />
|
|
181
186
|
</CardTitle>
|
|
182
187
|
</CardHeader>
|
|
183
188
|
<CardBody isFilled>
|
|
184
189
|
<Stack hasGutter>
|
|
185
190
|
<StackItem isFilled>
|
|
186
|
-
<div>{bundle.description}</div>
|
|
191
|
+
<div>{highlightMatch(bundle.description || '', searchTerm)}</div>
|
|
187
192
|
</StackItem>
|
|
188
193
|
<StackItem>
|
|
189
194
|
<Split>
|
|
@@ -206,9 +211,11 @@ const BundleCard = ({
|
|
|
206
211
|
const OperatorsBundle = ({
|
|
207
212
|
bundles,
|
|
208
213
|
preflightRequirements,
|
|
214
|
+
searchTerm,
|
|
209
215
|
}: {
|
|
210
216
|
bundles: Bundle[];
|
|
211
217
|
preflightRequirements: PreflightHardwareRequirements | undefined;
|
|
218
|
+
searchTerm?: string;
|
|
212
219
|
}) => {
|
|
213
220
|
const isSingleClusterFeatureEnabled = useFeature('ASSISTED_INSTALLER_SINGLE_CLUSTER_FEATURE');
|
|
214
221
|
|
|
@@ -216,7 +223,7 @@ const OperatorsBundle = ({
|
|
|
216
223
|
<Stack hasGutter>
|
|
217
224
|
<StackItem>
|
|
218
225
|
<Title headingLevel="h2" size="lg">
|
|
219
|
-
Bundles
|
|
226
|
+
{bundles.length > 0 ? 'Bundles' : ''}
|
|
220
227
|
</Title>
|
|
221
228
|
</StackItem>
|
|
222
229
|
<StackItem>
|
|
@@ -230,6 +237,7 @@ const OperatorsBundle = ({
|
|
|
230
237
|
bundle={bundle}
|
|
231
238
|
bundles={bundles}
|
|
232
239
|
preflightRequirements={preflightRequirements}
|
|
240
|
+
searchTerm={searchTerm}
|
|
233
241
|
/>
|
|
234
242
|
</GalleryItem>
|
|
235
243
|
))}
|