@openshift-assisted/ui-lib 2.54.2 → 2.55.0
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/cim/components/modals/CimConfiguration/CimStorageMissingAlert.d.ts.map +1 -1
- package/build/@types/cim/components/modals/CimConfiguration/constants.d.ts +1 -1
- package/build/@types/common/components/clusterConfiguration/utils.d.ts +9 -1
- package/build/@types/common/components/clusterConfiguration/utils.d.ts.map +1 -1
- package/build/@types/common/components/clusterWizard/networkingSteps/AvailableSubnetsControl.d.ts.map +1 -1
- package/build/@types/common/components/clusterWizard/networkingSteps/StackTypeControlGroup.d.ts.map +1 -1
- package/build/@types/common/components/operators/operatorSpecs.d.ts.map +1 -1
- package/build/@types/common/config/docs_links.d.ts.map +1 -1
- package/build/@types/ocm/components/Routes.d.ts +1 -1
- package/build/@types/ocm/components/Routes.d.ts.map +1 -1
- package/build/@types/ocm/components/clusterConfiguration/manifestsConfiguration/components/customManifestsValidationSchema.d.ts +10 -2
- package/build/@types/ocm/components/clusterConfiguration/manifestsConfiguration/components/customManifestsValidationSchema.d.ts.map +1 -1
- package/build/@types/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfiguration.d.ts.map +1 -1
- package/build/@types/ocm/components/clusterConfiguration/networkConfiguration/networkConfigurationValidation.d.ts.map +1 -1
- package/build/@types/ocm/components/clusterConfiguration/review/ReviewNetworkingTable.d.ts.map +1 -1
- package/build/@types/ocm/components/clusterConfiguration/review/utils.d.ts +1 -1
- package/build/@types/ocm/components/clusterConfiguration/review/utils.d.ts.map +1 -1
- package/build/@types/ocm/components/clusterDetail/AssistedInstallerDetailCard.d.ts +1 -1
- package/build/@types/ocm/components/clusterDetail/AssistedInstallerDetailCard.d.ts.map +1 -1
- package/build/@types/ocm/components/ui/Buttons/BackButton.d.ts +1 -1
- package/build/@types/ocm/components/ui/Buttons/BackButton.d.ts.map +1 -1
- package/build/@types/ocm/store/hooks.d.ts +1 -1
- package/build/@types/ocm/store/slices/clusters/selectors.d.ts +5 -61
- package/build/@types/ocm/store/slices/clusters/selectors.d.ts.map +1 -1
- package/build/@types/ocm/store/slices/feature-flags/selectors.d.ts +2 -20
- package/build/@types/ocm/store/slices/feature-flags/selectors.d.ts.map +1 -1
- package/build/@types/ocm/store/slices/infra-envs/selectors.d.ts +4 -21
- package/build/@types/ocm/store/slices/infra-envs/selectors.d.ts.map +1 -1
- package/build/cjs/cim/components/Agent/NoAgentsAlert.js +2 -2
- package/build/cjs/cim/components/Agent/NoAgentsAlert.js.map +1 -1
- package/build/cjs/cim/components/Agent/tableColumns.js +3 -3
- package/build/cjs/cim/components/Agent/tableColumns.js.map +1 -1
- package/build/cjs/cim/components/Hypershift/DetailsPage/NodePoolsTable.js +2 -2
- package/build/cjs/cim/components/Hypershift/DetailsPage/NodePoolsTable.js.map +1 -1
- package/build/cjs/cim/components/InfraEnv/AddHostDropdown.js +2 -2
- package/build/cjs/cim/components/InfraEnv/AddHostDropdown.js.map +1 -1
- package/build/cjs/cim/components/modals/CimConfiguration/CimConfigProgressAlert.js +3 -3
- package/build/cjs/cim/components/modals/CimConfiguration/CimConfigProgressAlert.js.map +1 -1
- package/build/cjs/cim/components/modals/CimConfiguration/CimConfigurationFormFields.js +1 -1
- package/build/cjs/cim/components/modals/CimConfiguration/CimConfigurationFormFields.js.map +1 -1
- package/build/cjs/cim/components/modals/CimConfiguration/CimConfigurationModal.js +2 -2
- package/build/cjs/cim/components/modals/CimConfiguration/CimConfigurationModal.js.map +1 -1
- package/build/cjs/cim/components/modals/CimConfiguration/CimStorageMissingAlert.js +3 -3
- package/build/cjs/cim/components/modals/CimConfiguration/CimStorageMissingAlert.js.map +1 -1
- package/build/cjs/cim/components/modals/CimConfiguration/constants.js +1 -1
- package/build/cjs/cim/components/modals/MassDeleteAgentModal.js +2 -2
- package/build/cjs/cim/components/modals/MassDeleteAgentModal.js.map +1 -1
- package/build/cjs/common/components/clusterConfiguration/utils.js +13 -1
- package/build/cjs/common/components/clusterConfiguration/utils.js.map +1 -1
- package/build/cjs/common/components/clusterConfiguration/utils.test.js +36 -0
- package/build/cjs/common/components/clusterConfiguration/utils.test.js.map +1 -1
- package/build/cjs/common/components/clusterWizard/networkingSteps/AvailableSubnetsControl.js +29 -31
- package/build/cjs/common/components/clusterWizard/networkingSteps/AvailableSubnetsControl.js.map +1 -1
- package/build/cjs/common/components/clusterWizard/networkingSteps/StackTypeControlGroup.js +19 -30
- package/build/cjs/common/components/clusterWizard/networkingSteps/StackTypeControlGroup.js.map +1 -1
- package/build/cjs/common/components/operators/operatorSpecs.js +0 -3
- package/build/cjs/common/components/operators/operatorSpecs.js.map +1 -1
- package/build/cjs/common/config/docs_links.js +2 -2
- package/build/cjs/common/config/docs_links.js.map +1 -1
- package/build/cjs/common/validationSchemas/addressValidation.js +1 -1
- package/build/cjs/common/validationSchemas/addressValidation.js.map +1 -1
- package/build/cjs/ocm/components/Routes.js +8 -8
- package/build/cjs/ocm/components/Routes.js.map +1 -1
- package/build/cjs/ocm/components/clusterConfiguration/manifestsConfiguration/components/customManifestsValidationSchema.js.map +1 -1
- package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfiguration.js +68 -17
- package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfiguration.js.map +1 -1
- package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfigurationForm.js +1 -1
- package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfigurationForm.js.map +1 -1
- package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/networkConfigurationValidation.js +50 -13
- package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/networkConfigurationValidation.js.map +1 -1
- package/build/cjs/ocm/components/clusterConfiguration/review/ReviewNetworkingTable.js +4 -2
- package/build/cjs/ocm/components/clusterConfiguration/review/ReviewNetworkingTable.js.map +1 -1
- package/build/cjs/ocm/components/clusterConfiguration/review/utils.js +7 -1
- package/build/cjs/ocm/components/clusterConfiguration/review/utils.js.map +1 -1
- package/build/cjs/ocm/components/clusterConfiguration/review/utils.test.js +35 -0
- package/build/cjs/ocm/components/clusterConfiguration/review/utils.test.js.map +1 -1
- package/build/cjs/ocm/components/clusterDetail/AssistedInstallerDetailCard.js +4 -4
- package/build/cjs/ocm/components/clusterDetail/AssistedInstallerDetailCard.js.map +1 -1
- package/build/cjs/ocm/components/clusterDetail/ClusterDetail.js +4 -4
- package/build/cjs/ocm/components/clusterDetail/ClusterDetail.js.map +1 -1
- package/build/cjs/ocm/components/clusterWizard/ClusterDetails.js +4 -4
- package/build/cjs/ocm/components/clusterWizard/ClusterDetails.js.map +1 -1
- package/build/cjs/ocm/components/clusterWizard/ClusterDetailsForm.js +2 -2
- package/build/cjs/ocm/components/clusterWizard/ClusterDetailsForm.js.map +1 -1
- package/build/cjs/ocm/components/clusterWizard/ClusterWizardContextProvider.js +2 -2
- package/build/cjs/ocm/components/clusterWizard/ClusterWizardContextProvider.js.map +1 -1
- package/build/cjs/ocm/components/clusterWizard/ClusterWizardFooter.js +2 -2
- package/build/cjs/ocm/components/clusterWizard/ClusterWizardFooter.js.map +1 -1
- package/build/cjs/ocm/components/clusterWizard/Operators.js +4 -4
- package/build/cjs/ocm/components/clusterWizard/Operators.js.map +1 -1
- package/build/cjs/ocm/components/clusterWizard/disconnected/ReviewStep.js +3 -3
- package/build/cjs/ocm/components/clusterWizard/disconnected/ReviewStep.js.map +1 -1
- package/build/cjs/ocm/components/clusters/ClusterBreadcrumbs.js +2 -2
- package/build/cjs/ocm/components/clusters/ClusterBreadcrumbs.js.map +1 -1
- package/build/cjs/ocm/components/clusters/ClusterPage.js +4 -4
- package/build/cjs/ocm/components/clusters/ClusterPage.js.map +1 -1
- package/build/cjs/ocm/components/clusters/Clusters.js +3 -3
- package/build/cjs/ocm/components/clusters/Clusters.js.map +1 -1
- package/build/cjs/ocm/components/clusters/ClustersListToolbar.js +3 -3
- package/build/cjs/ocm/components/clusters/ClustersListToolbar.js.map +1 -1
- package/build/cjs/ocm/components/ui/Buttons/BackButton.js +2 -2
- package/build/cjs/ocm/components/ui/Buttons/BackButton.js.map +1 -1
- package/build/cjs/ocm/store/slices/clusters/selectors.js +2 -2
- package/build/cjs/ocm/store/slices/clusters/selectors.js.map +1 -1
- package/build/cjs/ocm/store/slices/feature-flags/selectors.js.map +1 -1
- package/build/cjs/ocm/store/slices/infra-envs/selectors.js.map +1 -1
- package/lib/cim/components/Agent/NoAgentsAlert.tsx +1 -1
- package/lib/cim/components/Agent/tableColumns.tsx +1 -1
- package/lib/cim/components/Hypershift/DetailsPage/NodePoolsTable.tsx +1 -1
- package/lib/cim/components/InfraEnv/AddHostDropdown.tsx +1 -1
- package/lib/cim/components/modals/CimConfiguration/CimConfigProgressAlert.tsx +2 -2
- package/lib/cim/components/modals/CimConfiguration/CimConfigurationFormFields.tsx +1 -1
- package/lib/cim/components/modals/CimConfiguration/CimConfigurationModal.tsx +2 -2
- package/lib/cim/components/modals/CimConfiguration/CimStorageMissingAlert.tsx +5 -2
- package/lib/cim/components/modals/CimConfiguration/constants.ts +1 -1
- package/lib/cim/components/modals/MassDeleteAgentModal.tsx +1 -1
- package/lib/common/components/clusterConfiguration/utils.test.ts +43 -1
- package/lib/common/components/clusterConfiguration/utils.ts +13 -0
- package/lib/common/components/clusterWizard/networkingSteps/AvailableSubnetsControl.tsx +31 -57
- package/lib/common/components/clusterWizard/networkingSteps/StackTypeControlGroup.tsx +33 -38
- package/lib/common/components/operators/operatorSpecs.tsx +0 -16
- package/lib/common/config/docs_links.ts +2 -2
- package/lib/common/validationSchemas/addressValidation.tsx +2 -2
- package/lib/ocm/components/Routes.tsx +2 -2
- package/lib/ocm/components/clusterConfiguration/manifestsConfiguration/components/customManifestsValidationSchema.tsx +2 -2
- package/lib/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfiguration.tsx +86 -22
- package/lib/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfigurationForm.tsx +2 -2
- package/lib/ocm/components/clusterConfiguration/networkConfiguration/networkConfigurationValidation.ts +57 -20
- package/lib/ocm/components/clusterConfiguration/review/ReviewNetworkingTable.tsx +4 -2
- package/lib/ocm/components/clusterConfiguration/review/utils.test.ts +41 -0
- package/lib/ocm/components/clusterConfiguration/review/utils.tsx +5 -2
- package/lib/ocm/components/clusterDetail/AssistedInstallerDetailCard.tsx +1 -1
- package/lib/ocm/components/clusterDetail/ClusterDetail.tsx +3 -3
- package/lib/ocm/components/clusterWizard/ClusterDetails.tsx +2 -2
- package/lib/ocm/components/clusterWizard/ClusterDetailsForm.tsx +1 -1
- package/lib/ocm/components/clusterWizard/ClusterWizardContextProvider.tsx +1 -1
- package/lib/ocm/components/clusterWizard/ClusterWizardFooter.tsx +1 -1
- package/lib/ocm/components/clusterWizard/Operators.tsx +2 -2
- package/lib/ocm/components/clusterWizard/disconnected/ReviewStep.tsx +2 -2
- package/lib/ocm/components/clusters/ClusterBreadcrumbs.tsx +1 -1
- package/lib/ocm/components/clusters/ClusterPage.tsx +1 -1
- package/lib/ocm/components/clusters/Clusters.tsx +2 -2
- package/lib/ocm/components/clusters/ClustersListToolbar.tsx +2 -2
- package/lib/ocm/components/ui/Buttons/BackButton.tsx +1 -1
- package/lib/ocm/store/slices/clusters/selectors.tsx +7 -5
- package/lib/ocm/store/slices/feature-flags/selectors.ts +5 -2
- package/lib/ocm/store/slices/infra-envs/selectors.ts +4 -2
- package/package.json +8 -8
package/lib/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfiguration.tsx
CHANGED
|
@@ -6,13 +6,16 @@ import {
|
|
|
6
6
|
canBeDualStack,
|
|
7
7
|
CpuArchitecture,
|
|
8
8
|
DUAL_STACK,
|
|
9
|
+
getIPv6FromDualstack,
|
|
9
10
|
HostSubnets,
|
|
10
11
|
isAdvNetworkConf,
|
|
11
12
|
isSNO,
|
|
12
13
|
NetworkConfigurationValues,
|
|
14
|
+
NO_SUBNET_SET,
|
|
13
15
|
selectApiVip,
|
|
14
16
|
selectIngressVip,
|
|
15
17
|
} from '../../../../common';
|
|
18
|
+
import { Address6 } from 'ip-address';
|
|
16
19
|
import {
|
|
17
20
|
ManagedNetworkingControlGroup,
|
|
18
21
|
UserManagedNetworkingTextContent,
|
|
@@ -36,6 +39,7 @@ import {
|
|
|
36
39
|
} from '@openshift-assisted/types/assisted-installer-service';
|
|
37
40
|
import useSupportLevelsAPI from '../../../hooks/useSupportLevelsAPI';
|
|
38
41
|
import { isOciPlatformType } from '../../utils';
|
|
42
|
+
import { useFeature } from '../../../hooks/use-feature';
|
|
39
43
|
|
|
40
44
|
export type NetworkConfigurationProps = VirtualIPControlGroupProps & {
|
|
41
45
|
hostSubnets: HostSubnets;
|
|
@@ -122,6 +126,33 @@ const getManagedNetworkingState = (
|
|
|
122
126
|
};
|
|
123
127
|
};
|
|
124
128
|
|
|
129
|
+
type DefaultNetworkSettings = NetworkConfigurationProps['defaultNetworkSettings'];
|
|
130
|
+
|
|
131
|
+
const getNetworkDefaultsByFamily = (
|
|
132
|
+
settings: DefaultNetworkSettings,
|
|
133
|
+
isDualStack: boolean,
|
|
134
|
+
isIPv6: boolean,
|
|
135
|
+
) => {
|
|
136
|
+
if (isDualStack) {
|
|
137
|
+
return {
|
|
138
|
+
clusterNetworkDefaults: settings.clusterNetworksDualstack,
|
|
139
|
+
serviceNetworkDefaults: settings.serviceNetworksDualstack,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
if (isIPv6) {
|
|
143
|
+
const ipv6Cluster = getIPv6FromDualstack(settings.clusterNetworksDualstack);
|
|
144
|
+
const ipv6Service = getIPv6FromDualstack(settings.serviceNetworksDualstack);
|
|
145
|
+
return {
|
|
146
|
+
clusterNetworkDefaults: ipv6Cluster ? [ipv6Cluster] : settings.clusterNetworksIpv4,
|
|
147
|
+
serviceNetworkDefaults: ipv6Service ? [ipv6Service] : settings.serviceNetworksIpv4,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
clusterNetworkDefaults: settings.clusterNetworksIpv4,
|
|
152
|
+
serviceNetworkDefaults: settings.serviceNetworksIpv4,
|
|
153
|
+
};
|
|
154
|
+
};
|
|
155
|
+
|
|
125
156
|
const NetworkConfiguration = ({
|
|
126
157
|
cluster,
|
|
127
158
|
hostSubnets,
|
|
@@ -136,8 +167,10 @@ const NetworkConfiguration = ({
|
|
|
136
167
|
cluster.platform?.type,
|
|
137
168
|
);
|
|
138
169
|
const { isViewerMode } = useSelector(selectCurrentClusterPermissionsState);
|
|
139
|
-
const { setFieldValue, values, validateField } =
|
|
170
|
+
const { setFieldValue, values, validateField, validateForm } =
|
|
171
|
+
useFormikContext<NetworkConfigurationValues>();
|
|
140
172
|
|
|
173
|
+
const isSingleClusterFeature = useFeature('ASSISTED_INSTALLER_SINGLE_CLUSTER_FEATURE');
|
|
141
174
|
const isSNOCluster = isSNO(cluster);
|
|
142
175
|
const isUserManagedNetworking = values.managedNetworkingType === 'userManaged';
|
|
143
176
|
const isDualStack = values.stackType === DUAL_STACK;
|
|
@@ -177,30 +210,18 @@ const NetworkConfiguration = ({
|
|
|
177
210
|
setAdvanced(checked);
|
|
178
211
|
|
|
179
212
|
if (!checked) {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
);
|
|
187
|
-
setFieldValue(
|
|
188
|
-
'serviceNetworks',
|
|
189
|
-
isDualStack
|
|
190
|
-
? defaultNetworkSettings.serviceNetworksDualstack
|
|
191
|
-
: defaultNetworkSettings.serviceNetworksIpv4,
|
|
192
|
-
true,
|
|
213
|
+
const primaryCidr = values.machineNetworks?.[0]?.cidr;
|
|
214
|
+
const isIPv6Stack = !!primaryCidr && Address6.isValid(primaryCidr);
|
|
215
|
+
const { clusterNetworkDefaults, serviceNetworkDefaults } = getNetworkDefaultsByFamily(
|
|
216
|
+
defaultNetworkSettings,
|
|
217
|
+
isDualStack,
|
|
218
|
+
isIPv6Stack,
|
|
193
219
|
);
|
|
220
|
+
setFieldValue('clusterNetworks', clusterNetworkDefaults, true);
|
|
221
|
+
setFieldValue('serviceNetworks', serviceNetworkDefaults, true);
|
|
194
222
|
}
|
|
195
223
|
},
|
|
196
|
-
[
|
|
197
|
-
setFieldValue,
|
|
198
|
-
isDualStack,
|
|
199
|
-
defaultNetworkSettings.clusterNetworksDualstack,
|
|
200
|
-
defaultNetworkSettings.clusterNetworksIpv4,
|
|
201
|
-
defaultNetworkSettings.serviceNetworksDualstack,
|
|
202
|
-
defaultNetworkSettings.serviceNetworksIpv4,
|
|
203
|
-
],
|
|
224
|
+
[setFieldValue, isDualStack, values.machineNetworks, defaultNetworkSettings],
|
|
204
225
|
);
|
|
205
226
|
|
|
206
227
|
React.useEffect(() => {
|
|
@@ -209,6 +230,47 @@ const NetworkConfiguration = ({
|
|
|
209
230
|
}
|
|
210
231
|
}, [isDualStack, isViewerMode, toggleAdvConfiguration]);
|
|
211
232
|
|
|
233
|
+
React.useEffect(() => {
|
|
234
|
+
if (!isSingleClusterFeature || isViewerMode || isDualStack || isAdvanced) {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
const primaryCidr = values.machineNetworks?.[0]?.cidr;
|
|
238
|
+
if (!primaryCidr || primaryCidr === NO_SUBNET_SET) {
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
const isIPv6 = Address6.isValid(primaryCidr);
|
|
242
|
+
const currentClusterCidr = values.clusterNetworks?.[0]?.cidr;
|
|
243
|
+
const clusterIsIPv6 = currentClusterCidr ? Address6.isValid(currentClusterCidr) : null;
|
|
244
|
+
|
|
245
|
+
if (clusterIsIPv6 === isIPv6) {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const { clusterNetworkDefaults, serviceNetworkDefaults } = getNetworkDefaultsByFamily(
|
|
250
|
+
defaultNetworkSettings,
|
|
251
|
+
false,
|
|
252
|
+
isIPv6,
|
|
253
|
+
);
|
|
254
|
+
if (clusterNetworkDefaults) {
|
|
255
|
+
setFieldValue('clusterNetworks', clusterNetworkDefaults);
|
|
256
|
+
}
|
|
257
|
+
if (serviceNetworkDefaults) {
|
|
258
|
+
setFieldValue('serviceNetworks', serviceNetworkDefaults);
|
|
259
|
+
}
|
|
260
|
+
void validateForm();
|
|
261
|
+
}, [
|
|
262
|
+
isSingleClusterFeature,
|
|
263
|
+
isViewerMode,
|
|
264
|
+
isDualStack,
|
|
265
|
+
isAdvanced,
|
|
266
|
+
values.machineNetworks,
|
|
267
|
+
values.clusterNetworks,
|
|
268
|
+
defaultNetworkSettings,
|
|
269
|
+
setFieldValue,
|
|
270
|
+
validateForm,
|
|
271
|
+
cluster.id,
|
|
272
|
+
]);
|
|
273
|
+
|
|
212
274
|
const managedNetworkingState = React.useMemo(
|
|
213
275
|
() =>
|
|
214
276
|
getManagedNetworkingState(
|
|
@@ -252,6 +314,7 @@ const NetworkConfiguration = ({
|
|
|
252
314
|
hostSubnets={hostSubnets}
|
|
253
315
|
defaultNetworkValues={defaultNetworkSettings}
|
|
254
316
|
isViewerMode={isViewerMode}
|
|
317
|
+
allowSingleStackIPv6={isSingleClusterFeature}
|
|
255
318
|
/>
|
|
256
319
|
</StackItem>
|
|
257
320
|
)}
|
|
@@ -277,6 +340,7 @@ const NetworkConfiguration = ({
|
|
|
277
340
|
}
|
|
278
341
|
openshiftVersion={cluster.openshiftVersion}
|
|
279
342
|
isViewerMode={isViewerMode}
|
|
343
|
+
allowSingleStackIPv6={isSingleClusterFeature}
|
|
280
344
|
/>
|
|
281
345
|
</StackItem>
|
|
282
346
|
)}
|
package/lib/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfigurationForm.tsx
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
getFormikErrorFields,
|
|
10
10
|
getHostSubnets,
|
|
11
11
|
HostSubnets,
|
|
12
|
-
|
|
12
|
+
DUAL_STACK,
|
|
13
13
|
isSNO,
|
|
14
14
|
LoadingState,
|
|
15
15
|
NetworkConfigurationValues,
|
|
@@ -262,7 +262,7 @@ const NetworkConfigurationPage = ({ cluster }: { cluster: Cluster }) => {
|
|
|
262
262
|
if (values.vipDhcpAllocation) {
|
|
263
263
|
delete params.apiVips;
|
|
264
264
|
delete params.ingressVips;
|
|
265
|
-
} else if (values.stackType
|
|
265
|
+
} else if (values.stackType !== DUAL_STACK) {
|
|
266
266
|
// The API will rebuild the default machineNetwork
|
|
267
267
|
params.machineNetworks = [];
|
|
268
268
|
}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import * as Yup from 'yup';
|
|
2
2
|
import { TFunction } from 'i18next';
|
|
3
|
+
import { Address6 } from 'ip-address';
|
|
3
4
|
import {
|
|
4
5
|
clusterNetworksValidationSchema,
|
|
5
6
|
dualStackValidationSchema,
|
|
7
|
+
getIPv6FromDualstack,
|
|
8
|
+
isPrimaryIPv6,
|
|
6
9
|
HostSubnets,
|
|
7
10
|
isDualStack,
|
|
8
11
|
isSNO,
|
|
@@ -10,6 +13,7 @@ import {
|
|
|
10
13
|
NetworkConfigurationValues,
|
|
11
14
|
serviceNetworkValidationSchema,
|
|
12
15
|
IPv4ValidationSchema,
|
|
16
|
+
IPv6ValidationSchema,
|
|
13
17
|
sshPublicKeyValidationSchema,
|
|
14
18
|
SINGLE_STACK,
|
|
15
19
|
DUAL_STACK,
|
|
@@ -36,6 +40,38 @@ export const getNetworkInitialValues = (
|
|
|
36
40
|
): NetworkConfigurationValues => {
|
|
37
41
|
const isSNOCluster = isSNO(cluster);
|
|
38
42
|
const isDualStackType = isDualStack(cluster);
|
|
43
|
+
const primaryMachineNetworkCidr = cluster.machineNetworks?.[0]?.cidr;
|
|
44
|
+
const isIPv6OnlyStack =
|
|
45
|
+
!isDualStackType && !!primaryMachineNetworkCidr && Address6.isValid(primaryMachineNetworkCidr);
|
|
46
|
+
|
|
47
|
+
const getStackType = (): NetworkConfigurationValues['stackType'] => {
|
|
48
|
+
if (isDualStackType) return DUAL_STACK;
|
|
49
|
+
return SINGLE_STACK;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const getDefaultClusterNetworks = () => {
|
|
53
|
+
if (isDualStackType) return defaultNetworkValues.clusterNetworksDualstack;
|
|
54
|
+
if (isIPv6OnlyStack) {
|
|
55
|
+
const ipv6Entry = getIPv6FromDualstack(defaultNetworkValues.clusterNetworksDualstack);
|
|
56
|
+
return ipv6Entry ? [{ ...ipv6Entry, clusterId: cluster?.id }] : undefined;
|
|
57
|
+
}
|
|
58
|
+
return defaultNetworkValues.clusterNetworksIpv4?.map((network) => ({
|
|
59
|
+
...network,
|
|
60
|
+
clusterId: cluster?.id,
|
|
61
|
+
}));
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const getDefaultServiceNetworks = () => {
|
|
65
|
+
if (isDualStackType) return defaultNetworkValues.serviceNetworksDualstack;
|
|
66
|
+
if (isIPv6OnlyStack) {
|
|
67
|
+
const ipv6Entry = getIPv6FromDualstack(defaultNetworkValues.serviceNetworksDualstack);
|
|
68
|
+
return ipv6Entry ? [{ ...ipv6Entry, clusterId: cluster?.id }] : undefined;
|
|
69
|
+
}
|
|
70
|
+
return defaultNetworkValues.serviceNetworksIpv4?.map((network) => ({
|
|
71
|
+
...network,
|
|
72
|
+
clusterId: cluster?.id,
|
|
73
|
+
}));
|
|
74
|
+
};
|
|
39
75
|
|
|
40
76
|
return {
|
|
41
77
|
apiVips: cluster.apiVips,
|
|
@@ -50,23 +86,9 @@ export const getNetworkInitialValues = (
|
|
|
50
86
|
: 'clusterManaged',
|
|
51
87
|
networkType: cluster.networkType || NETWORK_TYPE_OVN,
|
|
52
88
|
machineNetworks: cluster.machineNetworks || [],
|
|
53
|
-
stackType:
|
|
54
|
-
clusterNetworks:
|
|
55
|
-
|
|
56
|
-
(isDualStackType
|
|
57
|
-
? defaultNetworkValues.clusterNetworksDualstack
|
|
58
|
-
: defaultNetworkValues.clusterNetworksIpv4?.map((network) => ({
|
|
59
|
-
...network,
|
|
60
|
-
clusterId: cluster?.id,
|
|
61
|
-
}))),
|
|
62
|
-
serviceNetworks:
|
|
63
|
-
cluster.serviceNetworks ||
|
|
64
|
-
(isDualStackType
|
|
65
|
-
? defaultNetworkValues.serviceNetworksDualstack
|
|
66
|
-
: defaultNetworkValues.serviceNetworksIpv4?.map((network) => ({
|
|
67
|
-
...network,
|
|
68
|
-
clusterId: cluster?.id,
|
|
69
|
-
}))),
|
|
89
|
+
stackType: getStackType(),
|
|
90
|
+
clusterNetworks: cluster.clusterNetworks || getDefaultClusterNetworks(),
|
|
91
|
+
serviceNetworks: cluster.serviceNetworks || getDefaultServiceNetworks(),
|
|
70
92
|
};
|
|
71
93
|
};
|
|
72
94
|
|
|
@@ -87,7 +109,12 @@ export const getNetworkConfigurationValidationSchema = (
|
|
|
87
109
|
: machineNetworksValidationSchema.when('stackType', {
|
|
88
110
|
is: (stackType: NetworkConfigurationValues['stackType']) =>
|
|
89
111
|
stackType === SINGLE_STACK,
|
|
90
|
-
then: () =>
|
|
112
|
+
then: () => {
|
|
113
|
+
if (isPrimaryIPv6(values.machineNetworks)) {
|
|
114
|
+
return machineNetworksValidationSchema.concat(IPv6ValidationSchema);
|
|
115
|
+
}
|
|
116
|
+
return machineNetworksValidationSchema.concat(IPv4ValidationSchema);
|
|
117
|
+
},
|
|
91
118
|
otherwise: () =>
|
|
92
119
|
values.machineNetworks && values.machineNetworks?.length >= 2
|
|
93
120
|
? machineNetworksValidationSchema.concat(
|
|
@@ -97,13 +124,23 @@ export const getNetworkConfigurationValidationSchema = (
|
|
|
97
124
|
}),
|
|
98
125
|
clusterNetworks: clusterNetworksValidationSchema(t).when('stackType', {
|
|
99
126
|
is: (stackType: NetworkConfigurationValues['stackType']) => stackType === SINGLE_STACK,
|
|
100
|
-
then: (schema) =>
|
|
127
|
+
then: (schema) => {
|
|
128
|
+
if (isPrimaryIPv6(values.machineNetworks)) {
|
|
129
|
+
return schema.concat(IPv6ValidationSchema);
|
|
130
|
+
}
|
|
131
|
+
return schema.concat(IPv4ValidationSchema);
|
|
132
|
+
},
|
|
101
133
|
otherwise: (schema) =>
|
|
102
134
|
schema.concat(dualStackValidationSchema('cluster network', t, openshiftVersion)),
|
|
103
135
|
}),
|
|
104
136
|
serviceNetworks: serviceNetworkValidationSchema(t).when('stackType', {
|
|
105
137
|
is: (stackType: NetworkConfigurationValues['stackType']) => stackType === SINGLE_STACK,
|
|
106
|
-
then: (schema) =>
|
|
138
|
+
then: (schema) => {
|
|
139
|
+
if (isPrimaryIPv6(values.machineNetworks)) {
|
|
140
|
+
return schema.concat(IPv6ValidationSchema);
|
|
141
|
+
}
|
|
142
|
+
return schema.concat(IPv4ValidationSchema);
|
|
143
|
+
},
|
|
107
144
|
otherwise: (schema) =>
|
|
108
145
|
schema.concat(dualStackValidationSchema('service network', t, openshiftVersion)),
|
|
109
146
|
}),
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
useTranslation,
|
|
9
9
|
} from '../../../../common';
|
|
10
10
|
import { getManagementType, getStackTypeLabel } from './utils';
|
|
11
|
+
import { useFeature } from '../../../hooks/use-feature';
|
|
11
12
|
import { Cluster } from '@openshift-assisted/types/assisted-installer-service';
|
|
12
13
|
|
|
13
14
|
type ReviewTableRowsType = {
|
|
@@ -17,6 +18,7 @@ type ReviewTableRowsType = {
|
|
|
17
18
|
|
|
18
19
|
export const ReviewNetworkingTable = ({ cluster }: { cluster: Cluster }) => {
|
|
19
20
|
const { t } = useTranslation();
|
|
21
|
+
const isSingleClusterFeature = useFeature('ASSISTED_INSTALLER_SINGLE_CLUSTER_FEATURE');
|
|
20
22
|
const rows = React.useMemo(() => {
|
|
21
23
|
const networkRows = [
|
|
22
24
|
{
|
|
@@ -34,7 +36,7 @@ export const ReviewNetworkingTable = ({ cluster }: { cluster: Cluster }) => {
|
|
|
34
36
|
cells: [
|
|
35
37
|
{ title: 'Stack type', colSpan: 2 },
|
|
36
38
|
{
|
|
37
|
-
title: getStackTypeLabel(cluster),
|
|
39
|
+
title: getStackTypeLabel(cluster, isSingleClusterFeature),
|
|
38
40
|
props: { 'data-testid': 'stack-type', colSpan: 2 },
|
|
39
41
|
},
|
|
40
42
|
],
|
|
@@ -125,7 +127,7 @@ export const ReviewNetworkingTable = ({ cluster }: { cluster: Cluster }) => {
|
|
|
125
127
|
});
|
|
126
128
|
|
|
127
129
|
return networkRows;
|
|
128
|
-
}, [cluster]);
|
|
130
|
+
}, [cluster, isSingleClusterFeature]);
|
|
129
131
|
|
|
130
132
|
const rowsAdvanced = React.useMemo(() => {
|
|
131
133
|
return [
|
|
@@ -169,6 +169,47 @@ describe('getStackTypeLabel', () => {
|
|
|
169
169
|
});
|
|
170
170
|
});
|
|
171
171
|
|
|
172
|
+
describe('with isSingleClusterFeature=true', () => {
|
|
173
|
+
test('returns "Single stack" for IPv4 single-stack cluster', () => {
|
|
174
|
+
const cluster = createCluster({
|
|
175
|
+
machineNetworks: [createMachineNetwork('192.168.1.0/24')],
|
|
176
|
+
clusterNetworks: [createClusterNetwork('10.128.0.0/14', 23)],
|
|
177
|
+
serviceNetworks: [createServiceNetwork('172.30.0.0/16')],
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
expect(getStackTypeLabel(cluster, true)).toBe('Single stack');
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
test('returns "Single stack" for IPv6 single-stack cluster', () => {
|
|
184
|
+
const cluster = createCluster({
|
|
185
|
+
machineNetworks: [createMachineNetwork('2001:db8::/64')],
|
|
186
|
+
clusterNetworks: [createClusterNetwork('fd01::/48', 64)],
|
|
187
|
+
serviceNetworks: [createServiceNetwork('fd02::/112')],
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
expect(getStackTypeLabel(cluster, true)).toBe('Single stack');
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
test('still returns "Dual-stack" for dual-stack cluster', () => {
|
|
194
|
+
const cluster = createCluster({
|
|
195
|
+
machineNetworks: [
|
|
196
|
+
createMachineNetwork('192.168.1.0/24'),
|
|
197
|
+
createMachineNetwork('2001:db8::/64'),
|
|
198
|
+
],
|
|
199
|
+
clusterNetworks: [
|
|
200
|
+
createClusterNetwork('10.128.0.0/14', 23),
|
|
201
|
+
createClusterNetwork('fd01::/48', 64),
|
|
202
|
+
],
|
|
203
|
+
serviceNetworks: [
|
|
204
|
+
createServiceNetwork('172.30.0.0/16'),
|
|
205
|
+
createServiceNetwork('fd02::/112'),
|
|
206
|
+
],
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
expect(getStackTypeLabel(cluster, true)).toBe('Dual-stack');
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
|
|
172
213
|
describe('edge cases', () => {
|
|
173
214
|
test('handles undefined openshiftVersion', () => {
|
|
174
215
|
const cluster = createCluster({
|
|
@@ -5,8 +5,11 @@ import { Cluster, DiskEncryption } from '@openshift-assisted/types/assisted-inst
|
|
|
5
5
|
export const getManagementType = ({ userManagedNetworking }: Cluster): string =>
|
|
6
6
|
userManagedNetworking ? 'User-managed networking' : 'Cluster-managed networking';
|
|
7
7
|
|
|
8
|
-
export const getStackTypeLabel = (cluster: Cluster): string =>
|
|
9
|
-
isDualStack(cluster)
|
|
8
|
+
export const getStackTypeLabel = (cluster: Cluster, isSingleClusterFeature = false): string => {
|
|
9
|
+
if (isDualStack(cluster)) return 'Dual-stack';
|
|
10
|
+
if (isSingleClusterFeature) return 'Single stack';
|
|
11
|
+
return 'IPv4';
|
|
12
|
+
};
|
|
10
13
|
|
|
11
14
|
export const getDiskEncryptionEnabledOnStatus = (diskEncryption: DiskEncryption['enableOn']) => {
|
|
12
15
|
let diskEncryptionType = null;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { useNavigate } from 'react-router
|
|
2
|
+
import { useNavigate } from 'react-router';
|
|
3
3
|
import { Stack, StackItem, Content, ButtonVariant, GridItem, Grid } from '@patternfly/react-core';
|
|
4
4
|
import { ToolbarButton, Alerts, getEnabledHosts, selectOlmOperators, isSNO } from '../../../common';
|
|
5
5
|
import { Cluster } from '@openshift-assisted/types/assisted-installer-service';
|
|
@@ -41,7 +41,7 @@ const ClusterDetail: React.FC<ClusterDetailProps> = ({ cluster }) => {
|
|
|
41
41
|
try {
|
|
42
42
|
const { data } = await ClustersAPI.allowAddHosts(cluster.id);
|
|
43
43
|
updateCluster(data);
|
|
44
|
-
navigate(`${routeBasePath}/clusters/${cluster.id}`);
|
|
44
|
+
void navigate(`${routeBasePath}/clusters/${cluster.id}`);
|
|
45
45
|
} catch (e) {
|
|
46
46
|
handleApiError(e);
|
|
47
47
|
}
|
|
@@ -102,7 +102,7 @@ const ClusterDetail: React.FC<ClusterDetailProps> = ({ cluster }) => {
|
|
|
102
102
|
{!isSingleClusterFeatureEnabled && (
|
|
103
103
|
<ToolbarButton
|
|
104
104
|
variant={ButtonVariant.link}
|
|
105
|
-
onClick={() => navigate('..')}
|
|
105
|
+
onClick={() => void navigate('..')}
|
|
106
106
|
id={getClusterDetailId('button-back-to-all-clusters')}
|
|
107
107
|
>
|
|
108
108
|
Back to all clusters
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { useLocation, useNavigate } from 'react-router
|
|
2
|
+
import { useLocation, useNavigate } from 'react-router';
|
|
3
3
|
import { useDispatch } from 'react-redux';
|
|
4
4
|
import {
|
|
5
5
|
useAlerts,
|
|
@@ -89,7 +89,7 @@ const ClusterDetails = ({ cluster, infraEnv }: ClusterDetailsProps) => {
|
|
|
89
89
|
isAssistedMigration,
|
|
90
90
|
isSingleClusterFeatureEnabled,
|
|
91
91
|
);
|
|
92
|
-
navigate(`../${cluster.id}`, { state: ClusterWizardFlowStateNew });
|
|
92
|
+
void navigate(`../${cluster.id}`, { state: ClusterWizardFlowStateNew });
|
|
93
93
|
|
|
94
94
|
if (isAssistedMigration) {
|
|
95
95
|
try {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { useSelector } from 'react-redux';
|
|
3
|
-
import { useLocation } from 'react-router
|
|
3
|
+
import { useLocation } from 'react-router';
|
|
4
4
|
import { Flex, Grid, GridItem } from '@patternfly/react-core';
|
|
5
5
|
import isUndefined from 'lodash-es/isUndefined.js';
|
|
6
6
|
import { Formik, FormikHelpers } from 'formik';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { PropsWithChildren } from 'react';
|
|
2
|
-
import { useLocation } from 'react-router
|
|
2
|
+
import { useLocation } from 'react-router';
|
|
3
3
|
import { ClusterWizardContextType, ClusterWizardContext } from './ClusterWizardContext';
|
|
4
4
|
import {
|
|
5
5
|
ClusterWizardFlowStateType,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { useDispatch } from 'react-redux';
|
|
3
|
-
import { useLocation, useNavigate } from 'react-router
|
|
3
|
+
import { useLocation, useNavigate } from 'react-router';
|
|
4
4
|
import { Formik, FormikConfig, useFormikContext } from 'formik';
|
|
5
5
|
import { Cluster } from '@openshift-assisted/types/assisted-installer-service';
|
|
6
6
|
import {
|
|
@@ -74,7 +74,7 @@ const OperatorsForm = ({ cluster }: { cluster: Cluster }) => {
|
|
|
74
74
|
|
|
75
75
|
const handleNext = () => {
|
|
76
76
|
if (window.location.pathname.indexOf('assisted-installer') > -1) {
|
|
77
|
-
navigate(pathname, { state: undefined, replace: true });
|
|
77
|
+
void navigate(pathname, { state: undefined, replace: true });
|
|
78
78
|
}
|
|
79
79
|
clusterWizardContext.moveNext();
|
|
80
80
|
};
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
} from '@patternfly/react-core';
|
|
27
27
|
import { Formik } from 'formik';
|
|
28
28
|
import { saveAs } from 'file-saver';
|
|
29
|
-
import { useNavigate } from 'react-router
|
|
29
|
+
import { useNavigate } from 'react-router';
|
|
30
30
|
|
|
31
31
|
import { getOperatorSpecs } from '../../../../common/components/operators/operatorSpecs';
|
|
32
32
|
|
|
@@ -51,7 +51,7 @@ const ReviewStep = () => {
|
|
|
51
51
|
<ClusterWizardFooter
|
|
52
52
|
onNext={() => {
|
|
53
53
|
downloadUrl && saveAs(downloadUrl);
|
|
54
|
-
navigate('/cluster-list');
|
|
54
|
+
void navigate('/cluster-list');
|
|
55
55
|
}}
|
|
56
56
|
onBack={moveBack}
|
|
57
57
|
nextButtonText="Download ISO"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Breadcrumb, BreadcrumbItem, PageSection } from '@patternfly/react-core';
|
|
3
|
-
import { Link } from 'react-router
|
|
3
|
+
import { Link } from 'react-router';
|
|
4
4
|
import { isInOcm } from '../../../common/api';
|
|
5
5
|
|
|
6
6
|
const ClusterBreadcrumbs = ({ clusterName }: { clusterName?: string }) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { useNavigate } from 'react-router
|
|
2
|
+
import { useNavigate } from 'react-router';
|
|
3
3
|
import { Button, ButtonVariant, Content, PageSection } from '@patternfly/react-core';
|
|
4
4
|
import { AddCircleOIcon } from '@patternfly/react-icons/dist/js/icons/add-circle-o-icon';
|
|
5
5
|
import {
|
|
@@ -85,7 +85,7 @@ const Clusters = () => {
|
|
|
85
85
|
primaryAction={
|
|
86
86
|
<Button
|
|
87
87
|
variant={ButtonVariant.primary}
|
|
88
|
-
onClick={() => navigate(`~new`)}
|
|
88
|
+
onClick={() => void navigate(`~new`)}
|
|
89
89
|
id="empty-state-new-cluster-button"
|
|
90
90
|
data-ouia-id="button-create-new-cluster"
|
|
91
91
|
>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { useNavigate } from 'react-router
|
|
2
|
+
import { useNavigate } from 'react-router';
|
|
3
3
|
import {
|
|
4
4
|
Toolbar,
|
|
5
5
|
ToolbarItem,
|
|
@@ -172,7 +172,7 @@ const ClustersListToolbar: React.FC<ClustersListToolbarProps> = ({
|
|
|
172
172
|
</CustomToolbarFilter>
|
|
173
173
|
<ToolbarButton
|
|
174
174
|
variant={ButtonVariant.primary}
|
|
175
|
-
onClick={() => navigate(`~new`)}
|
|
175
|
+
onClick={() => void navigate(`~new`)}
|
|
176
176
|
id="button-create-new-cluster"
|
|
177
177
|
data-ouia-id="button-create-new-cluster"
|
|
178
178
|
>
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { createSelector } from '@reduxjs/toolkit';
|
|
3
|
+
import type { Selector } from 'reselect';
|
|
3
4
|
import type { IRow, IRowData } from '@patternfly/react-table';
|
|
4
|
-
import { Link } from 'react-router
|
|
5
|
+
import { Link } from 'react-router';
|
|
5
6
|
import type { TFunction } from 'i18next';
|
|
6
7
|
import {
|
|
7
8
|
DASH,
|
|
@@ -22,7 +23,7 @@ const selectClusters = (state: RootStateDay1) =>
|
|
|
22
23
|
state.clusters.data.filter((c) => c.kind !== 'DisconnectedCluster');
|
|
23
24
|
const clustersUIState = (state: RootStateDay1) => state.clusters.uiState;
|
|
24
25
|
|
|
25
|
-
export const selectClustersUIState = createSelector(
|
|
26
|
+
export const selectClustersUIState: (state: RootStateDay1) => ResourceUIState = createSelector(
|
|
26
27
|
[selectClusters, clustersUIState],
|
|
27
28
|
(clusters, uiState): ResourceUIState => {
|
|
28
29
|
const { LOADED, EMPTY } = ResourceUIState;
|
|
@@ -95,13 +96,14 @@ const clusterToClusterTableRow = (cluster: Cluster, t: TFunction): IRow => {
|
|
|
95
96
|
export const getClusterTableStatusCell = (rowData: IRowData) =>
|
|
96
97
|
rowData?.cells?.[3] as HumanizedSortable;
|
|
97
98
|
|
|
98
|
-
export const selectClusterTableRows = (t: TFunction) => {
|
|
99
|
+
export const selectClusterTableRows = (t: TFunction): Selector<RootStateDay1, ClusterTableRows> => {
|
|
99
100
|
return createSelector(
|
|
100
101
|
selectClusters,
|
|
101
102
|
(clusters): ClusterTableRows => clusters.map((c) => clusterToClusterTableRow(c, t)),
|
|
102
103
|
);
|
|
103
104
|
};
|
|
104
105
|
|
|
105
|
-
export const selectClusterNames
|
|
106
|
-
|
|
106
|
+
export const selectClusterNames: Selector<RootStateDay1, (string | undefined)[]> = createSelector(
|
|
107
|
+
selectClusters,
|
|
108
|
+
(clusters) => clusters.map((c) => c.name),
|
|
107
109
|
);
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
import type { FeatureListType } from '../../../../common/features/featureGate';
|
|
2
2
|
import type { RootStateDay1 } from '../../store-day1';
|
|
3
3
|
import { createSelector } from '@reduxjs/toolkit';
|
|
4
|
+
import type { Selector } from 'reselect';
|
|
4
5
|
|
|
5
6
|
export const selectFeatureFlagsSlice = (state: RootStateDay1) => state.featureFlags;
|
|
6
7
|
|
|
7
|
-
export const isFeatureEnabled = (
|
|
8
|
+
export const isFeatureEnabled = (
|
|
9
|
+
featureId: keyof FeatureListType,
|
|
10
|
+
): Selector<RootStateDay1, boolean> =>
|
|
8
11
|
createSelector(
|
|
9
12
|
selectFeatureFlagsSlice,
|
|
10
|
-
(featureFlags: ReturnType<typeof selectFeatureFlagsSlice>) =>
|
|
13
|
+
(featureFlags: ReturnType<typeof selectFeatureFlagsSlice>): boolean =>
|
|
11
14
|
featureFlags.data[featureId] ?? false,
|
|
12
15
|
);
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { createSelector } from '@reduxjs/toolkit';
|
|
2
|
+
import type { Selector } from 'reselect';
|
|
2
3
|
import type { RootStateDay1 } from '../../store-day1';
|
|
3
4
|
import type { CpuArchitecture } from '../../../../common';
|
|
5
|
+
import type { InfraEnv } from '@openshift-assisted/types/assisted-installer-service';
|
|
4
6
|
|
|
5
7
|
export const selectInfraEnvsSlice = (state: RootStateDay1) => state.infraEnvs;
|
|
6
8
|
export const selectInfraEnvByCpuArchitecture = createSelector(
|
|
7
9
|
[selectInfraEnvsSlice, (_: RootStateDay1, cpuArchitecture: CpuArchitecture) => cpuArchitecture],
|
|
8
|
-
(infraEnvs, cpuArchitecture) =>
|
|
10
|
+
(infraEnvs, cpuArchitecture): InfraEnv | undefined =>
|
|
9
11
|
infraEnvs.find((infraEnv) => infraEnv.cpuArchitecture === cpuArchitecture),
|
|
10
|
-
)
|
|
12
|
+
) as Selector<RootStateDay1, InfraEnv | undefined, [CpuArchitecture]>;
|