@openshift-assisted/ui-lib 2.17.4-cim → 2.17.6-cim

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.
Files changed (48) hide show
  1. package/build/@types/cim/components/ClusterDeployment/NetworkConfiguration.d.ts +1 -1
  2. package/build/@types/cim/components/ClusterDeployment/NetworkConfiguration.d.ts.map +1 -1
  3. package/build/@types/cim/components/ClusterDeployment/networkConfigurationValidation.d.ts +1 -1
  4. package/build/@types/cim/components/ClusterDeployment/networkConfigurationValidation.d.ts.map +1 -1
  5. package/build/@types/cim/components/ClusterDeployment/use-networking-formik.d.ts +4 -4
  6. package/build/@types/cim/components/ClusterDeployment/use-networking-formik.d.ts.map +1 -1
  7. package/build/@types/common/components/clusterWizard/networkingSteps/AvailableSubnetsControl.d.ts +2 -1
  8. package/build/@types/common/components/clusterWizard/networkingSteps/AvailableSubnetsControl.d.ts.map +1 -1
  9. package/build/@types/common/components/clusterWizard/networkingSteps/StackTypeControlGroup.d.ts +2 -1
  10. package/build/@types/common/components/clusterWizard/networkingSteps/StackTypeControlGroup.d.ts.map +1 -1
  11. package/build/@types/common/components/ui/formik/utils.d.ts +1 -0
  12. package/build/@types/common/components/ui/formik/utils.d.ts.map +1 -1
  13. package/build/@types/common/config/constants.d.ts +2 -2
  14. package/build/@types/common/config/constants.d.ts.map +1 -1
  15. package/build/@types/common/validationSchemas/networkingValidation.d.ts +10 -0
  16. package/build/@types/common/validationSchemas/networkingValidation.d.ts.map +1 -1
  17. package/build/@types/ocm/components/clusterConfiguration/networkConfiguration/networkConfigurationValidation.d.ts.map +1 -1
  18. package/build/cjs/cim/components/ClusterDeployment/NetworkConfiguration.js +44 -5
  19. package/build/cjs/cim/components/ClusterDeployment/NetworkConfiguration.js.map +1 -1
  20. package/build/cjs/cim/components/ClusterDeployment/networkConfigurationValidation.js +27 -11
  21. package/build/cjs/cim/components/ClusterDeployment/networkConfigurationValidation.js.map +1 -1
  22. package/build/cjs/cim/components/ClusterDeployment/use-networking-formik.js +13 -18
  23. package/build/cjs/cim/components/ClusterDeployment/use-networking-formik.js.map +1 -1
  24. package/build/cjs/common/components/clusterWizard/networkingSteps/AvailableSubnetsControl.js +8 -2
  25. package/build/cjs/common/components/clusterWizard/networkingSteps/AvailableSubnetsControl.js.map +1 -1
  26. package/build/cjs/common/components/clusterWizard/networkingSteps/StackTypeControlGroup.js +29 -19
  27. package/build/cjs/common/components/clusterWizard/networkingSteps/StackTypeControlGroup.js.map +1 -1
  28. package/build/cjs/common/components/ui/formik/utils.js +5 -1
  29. package/build/cjs/common/components/ui/formik/utils.js.map +1 -1
  30. package/build/cjs/common/config/constants.js +9 -2
  31. package/build/cjs/common/config/constants.js.map +1 -1
  32. package/build/cjs/common/validationSchemas/networkingValidation.js +19 -1
  33. package/build/cjs/common/validationSchemas/networkingValidation.js.map +1 -1
  34. package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfigurationForm.js +1 -1
  35. package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfigurationForm.js.map +1 -1
  36. package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/networkConfigurationValidation.js +4 -4
  37. package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/networkConfigurationValidation.js.map +1 -1
  38. package/lib/cim/components/ClusterDeployment/NetworkConfiguration.tsx +51 -3
  39. package/lib/cim/components/ClusterDeployment/networkConfigurationValidation.ts +22 -8
  40. package/lib/cim/components/ClusterDeployment/use-networking-formik.ts +14 -22
  41. package/lib/common/components/clusterWizard/networkingSteps/AvailableSubnetsControl.tsx +8 -1
  42. package/lib/common/components/clusterWizard/networkingSteps/StackTypeControlGroup.tsx +37 -27
  43. package/lib/common/components/ui/formik/utils.ts +6 -0
  44. package/lib/common/config/constants.ts +10 -1
  45. package/lib/common/validationSchemas/networkingValidation.tsx +39 -1
  46. package/lib/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfigurationForm.tsx +2 -2
  47. package/lib/ocm/components/clusterConfiguration/networkConfiguration/networkConfigurationValidation.ts +6 -5
  48. package/package.json +3 -3
@@ -7,13 +7,14 @@ import { HostSubnets, NetworkConfigurationValues } from '../../../types';
7
7
  import { getFieldId } from '../../ui';
8
8
  import {
9
9
  DUAL_STACK,
10
- IPV4_STACK,
10
+ NO_SUBNET_SET,
11
+ SINGLE_STACK,
11
12
  NETWORK_TYPE_OVN,
12
13
  NETWORK_TYPE_SDN,
13
- NO_SUBNET_SET,
14
14
  } from '../../../config';
15
15
  import { RadioField } from '../../ui/formik';
16
16
  import { ConfirmationModal, PopoverIcon } from '../../ui';
17
+ import { useTranslation } from '../../../hooks/use-translation-wrapper';
17
18
  import { reorderNetworksByCurrentPrimary } from './reorderNetworks';
18
19
  import {
19
20
  Cluster,
@@ -37,6 +38,7 @@ export type StackTypeControlGroupProps = {
37
38
  hostSubnets: HostSubnets;
38
39
  defaultNetworkValues: StackTypeDefaultNetworkValues;
39
40
  isViewerMode?: boolean;
41
+ allowSingleStackIPv6?: boolean;
40
42
  };
41
43
 
42
44
  const hasDualStackConfigurationChanged = (
@@ -61,17 +63,21 @@ export const StackTypeControlGroup = ({
61
63
  hostSubnets,
62
64
  defaultNetworkValues,
63
65
  isViewerMode = false,
66
+ allowSingleStackIPv6 = false,
64
67
  }: StackTypeControlGroupProps) => {
68
+ const { t } = useTranslation();
65
69
  const { setFieldValue, values, validateForm } = useFormikContext<NetworkConfigurationValues>();
66
70
  const [openConfirmModal, setConfirmModal] = React.useState(false);
67
71
 
72
+ const singleStackLabel = allowSingleStackIPv6 ? t('ai:Single stack') : t('ai:IPv4');
73
+
68
74
  const IPv6Subnets = hostSubnets.filter((subnet) => Address6.isValid(subnet.subnet));
69
75
  const cidrIPv6 = IPv6Subnets.length >= 1 ? IPv6Subnets[0].subnet : NO_SUBNET_SET;
70
76
  const shouldSetSingleStack =
71
77
  !isViewerMode && !isDualStackSelectable && values.stackType === DUAL_STACK;
72
78
 
73
79
  const setSingleStack = React.useCallback(() => {
74
- setFieldValue('stackType', IPV4_STACK);
80
+ setFieldValue('stackType', SINGLE_STACK);
75
81
 
76
82
  // Determine whether the first machine network is IPv4
77
83
  const firstNetwork = values.machineNetworks?.[0];
@@ -95,7 +101,8 @@ export const StackTypeControlGroup = ({
95
101
  }
96
102
  }
97
103
  }
98
- // Ensure single-stack inputs are IPv4 after switching from dual-stack
104
+
105
+ // Set cluster/service to IPv4 defaults when switching to single-stack
99
106
  if (values.clusterNetworks && values.clusterNetworks.length >= 1) {
100
107
  const defaultCluster =
101
108
  defaultNetworkValues.clusterNetworksIpv4 && defaultNetworkValues.clusterNetworksIpv4[0];
@@ -197,28 +204,27 @@ export const StackTypeControlGroup = ({
197
204
  }
198
205
  }
199
206
  if (values.clusterNetworks && values.clusterNetworks?.length < 2) {
200
- setFieldValue(
201
- 'clusterNetworks',
202
- [
203
- ...values.clusterNetworks,
204
- defaultNetworkValues.clusterNetworksDualstack?.length
205
- ? defaultNetworkValues.clusterNetworksDualstack[1]
206
- : { cidr: '', hostPrefix: '', clusterId: clusterId },
207
- ],
208
- false,
209
- );
207
+ const firstClusterCidr = values.clusterNetworks[0]?.cidr;
208
+ const isPrimaryIPv6 = firstClusterCidr && Address6.isValid(firstClusterCidr);
209
+ const missingFamilyNetworkDefault =
210
+ defaultNetworkValues.clusterNetworksDualstack?.[isPrimaryIPv6 ? 0 : 1];
211
+ const secondClusterNetwork = missingFamilyNetworkDefault ?? {
212
+ cidr: '',
213
+ hostPrefix: '',
214
+ clusterId: clusterId,
215
+ };
216
+ setFieldValue('clusterNetworks', [...values.clusterNetworks, secondClusterNetwork], false);
210
217
  }
211
218
  if (values.serviceNetworks && values.serviceNetworks?.length < 2) {
212
- setFieldValue(
213
- 'serviceNetworks',
214
- [
215
- ...values.serviceNetworks,
216
- defaultNetworkValues.serviceNetworksDualstack?.length
217
- ? defaultNetworkValues.serviceNetworksDualstack[1]
218
- : { cidr: '', clusterId: clusterId },
219
- ],
220
- false,
221
- );
219
+ const firstServiceCidr = values.serviceNetworks[0]?.cidr;
220
+ const isPrimaryIPv6 = firstServiceCidr && Address6.isValid(firstServiceCidr);
221
+ const missingFamilyNetworkDefault =
222
+ defaultNetworkValues.serviceNetworksDualstack?.[isPrimaryIPv6 ? 0 : 1];
223
+ const secondServiceNetwork = missingFamilyNetworkDefault ?? {
224
+ cidr: '',
225
+ clusterId: clusterId,
226
+ };
227
+ setFieldValue('serviceNetworks', [...values.serviceNetworks, secondServiceNetwork], false);
222
228
  }
223
229
  // Initialize VIPs for dual-stack
224
230
  if (values.apiVips && values.apiVips.length < 2) {
@@ -291,14 +297,18 @@ export const StackTypeControlGroup = ({
291
297
  <SplitItem>
292
298
  <RadioField
293
299
  name={'stackType'}
294
- value={IPV4_STACK}
300
+ value={SINGLE_STACK}
295
301
  isDisabled={!isDualStackSelectable || isViewerMode}
296
- label="IPv4&nbsp;"
302
+ label={`${singleStackLabel}\u00A0`}
297
303
  />
298
304
  </SplitItem>
299
305
  <SplitItem>
300
306
  <PopoverIcon
301
- bodyContent="Select this when your hosts are using only IPv4."
307
+ bodyContent={
308
+ allowSingleStackIPv6
309
+ ? t('ai:Select a single address family (IPv4 or IPv6) for your machine network.')
310
+ : t('ai:Select this when your hosts are using only IPv4.')
311
+ }
302
312
  buttonStyle={{ top: '-4px' }}
303
313
  />
304
314
  </SplitItem>
@@ -126,6 +126,12 @@ export const allSubnetsIPv4 = (
126
126
  return !!networks?.every((network) => network.cidr && Address4.isValid(network.cidr));
127
127
  };
128
128
 
129
+ export const allSubnetsIPv6 = (
130
+ networks: (MachineNetwork | ClusterNetwork | ServiceNetwork)[] | undefined,
131
+ ) => {
132
+ return !!networks?.every((network) => network.cidr && Address6.isValid(network.cidr));
133
+ };
134
+
129
135
  export const labelsToArray = (labels: { [key in string]: string } = {}): string[] => {
130
136
  const result: string[] = [];
131
137
  for (const key in labels) {
@@ -287,8 +287,10 @@ export const CLUSTER_DEFAULT_NETWORK_SETTINGS_IPV6 = {
287
287
  export const CLUSTER_DEFAULT_NETWORK_SETTINGS: Pick<
288
288
  ClusterDefaultConfig,
289
289
  | 'clusterNetworksIpv4'
290
+ | 'clusterNetworksIpv6'
290
291
  | 'clusterNetworksDualstack'
291
292
  | 'serviceNetworksIpv4'
293
+ | 'serviceNetworksIpv6'
292
294
  | 'serviceNetworksDualstack'
293
295
  > = {
294
296
  clusterNetworksIpv4: [
@@ -297,6 +299,12 @@ export const CLUSTER_DEFAULT_NETWORK_SETTINGS: Pick<
297
299
  hostPrefix: CLUSTER_DEFAULT_NETWORK_SETTINGS_IPV4.clusterNetworkHostPrefix,
298
300
  },
299
301
  ],
302
+ clusterNetworksIpv6: [
303
+ {
304
+ cidr: CLUSTER_DEFAULT_NETWORK_SETTINGS_IPV6.clusterNetworkCidr,
305
+ hostPrefix: CLUSTER_DEFAULT_NETWORK_SETTINGS_IPV6.clusterNetworkHostPrefix,
306
+ },
307
+ ],
300
308
  clusterNetworksDualstack: [
301
309
  {
302
310
  cidr: CLUSTER_DEFAULT_NETWORK_SETTINGS_IPV4.clusterNetworkCidr,
@@ -308,6 +316,7 @@ export const CLUSTER_DEFAULT_NETWORK_SETTINGS: Pick<
308
316
  },
309
317
  ],
310
318
  serviceNetworksIpv4: [{ cidr: CLUSTER_DEFAULT_NETWORK_SETTINGS_IPV4.serviceNetworkCidr }],
319
+ serviceNetworksIpv6: [{ cidr: CLUSTER_DEFAULT_NETWORK_SETTINGS_IPV6.serviceNetworkCidr }],
311
320
  serviceNetworksDualstack: [
312
321
  { cidr: CLUSTER_DEFAULT_NETWORK_SETTINGS_IPV4.serviceNetworkCidr },
313
322
  { cidr: CLUSTER_DEFAULT_NETWORK_SETTINGS_IPV6.serviceNetworkCidr },
@@ -334,7 +343,7 @@ export const NO_SUBNET_SET = 'NO_SUBNET_SET';
334
343
  export const NETWORK_TYPE_OVN = 'OVNKubernetes';
335
344
  export const NETWORK_TYPE_SDN = 'OpenShiftSDN';
336
345
 
337
- export const IPV4_STACK = 'singleStack';
346
+ export const SINGLE_STACK = 'singleStack';
338
347
  export const DUAL_STACK = 'dualStack';
339
348
 
340
349
  export const PREFIX_MAX_RESTRICTION = {
@@ -13,7 +13,8 @@ import {
13
13
  ipBlockValidationSchema,
14
14
  } from './addressValidation';
15
15
  import { isMajorMinorVersionEqualOrGreater } from '../utils';
16
- import { allSubnetsIPv4 } from '../components/ui/formik/utils';
16
+ import { allSubnetsIPv4, allSubnetsIPv6 } from '../components/ui/formik/utils';
17
+ import { SINGLE_STACK } from '../config';
17
18
 
18
19
  export const machineNetworksValidationSchema = Yup.array().of(
19
20
  Yup.object({ cidr: hostSubnetValidationSchema, clusterId: Yup.string() }),
@@ -111,3 +112,40 @@ export const IPv4ValidationSchema = Yup.array().test(
111
112
  `All network subnets must be IPv4.`,
112
113
  (values?: (MachineNetwork | ClusterNetwork | ServiceNetwork)[]) => allSubnetsIPv4(values),
113
114
  );
115
+
116
+ export const IPv6ValidationSchema = Yup.array().test(
117
+ 'single-stack-ipv6',
118
+ 'All network subnets must be IPv6.',
119
+ (values?: (MachineNetwork | ClusterNetwork | ServiceNetwork)[]) => allSubnetsIPv6(values),
120
+ );
121
+
122
+ export const clusterNetworksSchema = (
123
+ t: TFunction,
124
+ stackType: string,
125
+ primaryCidr: string | undefined,
126
+ openshiftVersion?: string,
127
+ ) => {
128
+ const singleStackFamilySchema =
129
+ primaryCidr && isCIDR.v6(primaryCidr) ? IPv6ValidationSchema : IPv4ValidationSchema;
130
+
131
+ const stackFamilySchema =
132
+ stackType === SINGLE_STACK
133
+ ? singleStackFamilySchema
134
+ : dualStackValidationSchema(t('ai:cluster network'), t, openshiftVersion);
135
+ return clusterNetworksValidationSchema(t).concat(stackFamilySchema);
136
+ };
137
+
138
+ export const serviceNetworksSchema = (
139
+ t: TFunction,
140
+ stackType: string,
141
+ primaryCidr: string | undefined,
142
+ openshiftVersion?: string,
143
+ ) => {
144
+ const singleStackFamilySchema =
145
+ primaryCidr && isCIDR.v6(primaryCidr) ? IPv6ValidationSchema : IPv4ValidationSchema;
146
+ const stackFamilySchema =
147
+ stackType === SINGLE_STACK
148
+ ? singleStackFamilySchema
149
+ : dualStackValidationSchema(t('ai:service network'), t, openshiftVersion);
150
+ return serviceNetworkValidationSchema(t).concat(stackFamilySchema);
151
+ };
@@ -9,7 +9,7 @@ import {
9
9
  getFormikErrorFields,
10
10
  getHostSubnets,
11
11
  HostSubnets,
12
- IPV4_STACK,
12
+ SINGLE_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 === IPV4_STACK) {
265
+ } else if (values.stackType === SINGLE_STACK) {
266
266
  // The API will rebuild the default machineNetwork
267
267
  params.machineNetworks = [];
268
268
  }
@@ -11,7 +11,7 @@ import {
11
11
  serviceNetworkValidationSchema,
12
12
  IPv4ValidationSchema,
13
13
  sshPublicKeyValidationSchema,
14
- IPV4_STACK,
14
+ SINGLE_STACK,
15
15
  DUAL_STACK,
16
16
  vipArrayValidationSchema,
17
17
  NETWORK_TYPE_OVN,
@@ -50,7 +50,7 @@ export const getNetworkInitialValues = (
50
50
  : 'clusterManaged',
51
51
  networkType: cluster.networkType || NETWORK_TYPE_OVN,
52
52
  machineNetworks: cluster.machineNetworks || [],
53
- stackType: isDualStackType ? DUAL_STACK : IPV4_STACK,
53
+ stackType: isDualStackType ? DUAL_STACK : SINGLE_STACK,
54
54
  clusterNetworks:
55
55
  cluster.clusterNetworks ||
56
56
  (isDualStackType
@@ -85,7 +85,8 @@ export const getNetworkConfigurationValidationSchema = (
85
85
  values.managedNetworkingType === 'userManaged'
86
86
  ? Yup.array()
87
87
  : machineNetworksValidationSchema.when('stackType', {
88
- is: (stackType: NetworkConfigurationValues['stackType']) => stackType === IPV4_STACK,
88
+ is: (stackType: NetworkConfigurationValues['stackType']) =>
89
+ stackType === SINGLE_STACK,
89
90
  then: () => machineNetworksValidationSchema.concat(IPv4ValidationSchema),
90
91
  otherwise: () =>
91
92
  values.machineNetworks && values.machineNetworks?.length >= 2
@@ -95,13 +96,13 @@ export const getNetworkConfigurationValidationSchema = (
95
96
  : Yup.array(),
96
97
  }),
97
98
  clusterNetworks: clusterNetworksValidationSchema(t).when('stackType', {
98
- is: (stackType: NetworkConfigurationValues['stackType']) => stackType === IPV4_STACK,
99
+ is: (stackType: NetworkConfigurationValues['stackType']) => stackType === SINGLE_STACK,
99
100
  then: (schema) => schema.concat(IPv4ValidationSchema),
100
101
  otherwise: (schema) =>
101
102
  schema.concat(dualStackValidationSchema('cluster network', t, openshiftVersion)),
102
103
  }),
103
104
  serviceNetworks: serviceNetworkValidationSchema(t).when('stackType', {
104
- is: (stackType: NetworkConfigurationValues['stackType']) => stackType === IPV4_STACK,
105
+ is: (stackType: NetworkConfigurationValues['stackType']) => stackType === SINGLE_STACK,
105
106
  then: (schema) => schema.concat(IPv4ValidationSchema),
106
107
  otherwise: (schema) =>
107
108
  schema.concat(dualStackValidationSchema('service network', t, openshiftVersion)),
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "dependencies": {
3
- "@openshift-assisted/locales": "2.17.4-cim",
4
- "@openshift-assisted/types": "2.17.4-cim",
3
+ "@openshift-assisted/locales": "2.17.6-cim",
4
+ "@openshift-assisted/types": "2.17.6-cim",
5
5
  "@openshift-console/dynamic-plugin-sdk": "1.0.0",
6
6
  "@patternfly/patternfly": "6.2.3",
7
7
  "@patternfly/react-code-editor": "6.2.2",
@@ -140,5 +140,5 @@
140
140
  ]
141
141
  }
142
142
  },
143
- "version": "2.17.4-cim"
143
+ "version": "2.17.6-cim"
144
144
  }