@openshift-assisted/ui-lib 2.51.0 → 2.51.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.
Files changed (190) hide show
  1. package/build/@types/common/api/assisted-service/ClustersAPI.d.ts +0 -4
  2. package/build/@types/common/api/assisted-service/ClustersAPI.d.ts.map +1 -1
  3. package/build/@types/common/components/clusterWizard/clusterDetailsValidation.d.ts.map +1 -1
  4. package/build/@types/common/components/clusterWizard/networkingSteps/StackTypeControlGroup.d.ts.map +1 -1
  5. package/build/@types/common/components/clusterWizard/networkingSteps/VirtualIPControlGroup.d.ts.map +1 -1
  6. package/build/@types/common/components/ui/OpenShiftVersionModal.d.ts.map +1 -1
  7. package/build/@types/common/components/ui/formik/PullSecretField.d.ts.map +1 -1
  8. package/build/@types/common/config/constants.d.ts +0 -7
  9. package/build/@types/common/config/constants.d.ts.map +1 -1
  10. package/build/@types/common/types/index.d.ts +1 -0
  11. package/build/@types/common/types/index.d.ts.map +1 -1
  12. package/build/@types/common/types/networkType.d.ts +12 -0
  13. package/build/@types/common/types/networkType.d.ts.map +1 -0
  14. package/build/@types/common/validationSchemas/addressValidation.d.ts.map +1 -1
  15. package/build/@types/common/validationSchemas/clusterDetailsValidation.d.ts +0 -5
  16. package/build/@types/common/validationSchemas/clusterDetailsValidation.d.ts.map +1 -1
  17. package/build/@types/ocm/components/Routes.d.ts.map +1 -1
  18. package/build/@types/ocm/components/clusterConfiguration/DiscoveryImageTypeDropdown.d.ts.map +1 -1
  19. package/build/@types/ocm/components/clusterConfiguration/OcmDiscoveryImageConfigForm.d.ts +2 -2
  20. package/build/@types/ocm/components/clusterConfiguration/OcmDiscoveryImageConfigForm.d.ts.map +1 -1
  21. package/build/@types/ocm/components/clusterConfiguration/manifestsConfiguration/CustomManifestsPage.d.ts.map +1 -1
  22. package/build/@types/ocm/components/clusterConfiguration/manifestsConfiguration/components/CustomManifestsArray.d.ts.map +1 -1
  23. package/build/@types/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfiguration.d.ts.map +1 -1
  24. package/build/@types/ocm/components/clusterConfiguration/networkConfiguration/NetworkTypeDropdown.d.ts +1 -2
  25. package/build/@types/ocm/components/clusterConfiguration/networkConfiguration/NetworkTypeDropdown.d.ts.map +1 -1
  26. package/build/@types/ocm/components/clusterConfiguration/review/ReviewStep.d.ts.map +1 -1
  27. package/build/@types/ocm/components/clusterConfiguration/staticIp/commonValidationSchemas.d.ts.map +1 -1
  28. package/build/@types/ocm/components/clusterConfiguration/staticIp/components/FormViewHosts/FormViewHostsFields.d.ts.map +1 -1
  29. package/build/@types/ocm/components/clusterConfiguration/staticIp/components/FormViewNetworkWide/formViewNetworkWideValidationSchema.d.ts +0 -22
  30. package/build/@types/ocm/components/clusterConfiguration/staticIp/components/FormViewNetworkWide/formViewNetworkWideValidationSchema.d.ts.map +1 -1
  31. package/build/@types/ocm/components/clusterWizard/ClusterDetails.d.ts.map +1 -1
  32. package/build/@types/ocm/components/clusterWizard/ClusterDetailsForm.d.ts.map +1 -1
  33. package/build/@types/ocm/components/clusterWizard/ClusterWizardContext.d.ts +0 -3
  34. package/build/@types/ocm/components/clusterWizard/ClusterWizardContext.d.ts.map +1 -1
  35. package/build/@types/ocm/components/clusterWizard/ClusterWizardContextProvider.d.ts.map +1 -1
  36. package/build/@types/ocm/components/clusterWizard/ClusterWizardFooter.d.ts +1 -2
  37. package/build/@types/ocm/components/clusterWizard/ClusterWizardFooter.d.ts.map +1 -1
  38. package/build/@types/ocm/components/clusterWizard/NewClusterWizard.d.ts.map +1 -1
  39. package/build/@types/ocm/components/clusterWizard/constants.d.ts.map +1 -1
  40. package/build/@types/ocm/components/clusterWizard/disconnected/BasicStep.d.ts.map +1 -1
  41. package/build/@types/ocm/components/clusterWizard/disconnected/ReviewStep.d.ts.map +1 -1
  42. package/build/@types/ocm/components/clusterWizard/index.d.ts +0 -1
  43. package/build/@types/ocm/components/clusterWizard/index.d.ts.map +1 -1
  44. package/build/@types/ocm/components/clusterWizard/wizardTransition.d.ts +1 -1
  45. package/build/@types/ocm/components/clusterWizard/wizardTransition.d.ts.map +1 -1
  46. package/build/@types/ocm/components/featureSupportLevels/featureStateUtils.d.ts.map +1 -1
  47. package/build/@types/ocm/components/utils.d.ts +0 -1
  48. package/build/@types/ocm/components/utils.d.ts.map +1 -1
  49. package/build/@types/ocm/services/ClustersService.d.ts +0 -4
  50. package/build/@types/ocm/services/ClustersService.d.ts.map +1 -1
  51. package/build/@types/ocm/services/InfraEnvsService.d.ts.map +1 -1
  52. package/build/@types/ocm/store/slices/clusters/selectors.d.ts +1 -2
  53. package/build/@types/ocm/store/slices/clusters/selectors.d.ts.map +1 -1
  54. package/build/cjs/cim/components/ClusterDeployment/networkConfigurationValidation.js +3 -3
  55. package/build/cjs/cim/components/ClusterDeployment/networkConfigurationValidation.js.map +1 -1
  56. package/build/cjs/common/api/assisted-service/ClustersAPI.js +0 -3
  57. package/build/cjs/common/api/assisted-service/ClustersAPI.js.map +1 -1
  58. package/build/cjs/common/components/clusterWizard/clusterDetailsValidation.js +8 -17
  59. package/build/cjs/common/components/clusterWizard/clusterDetailsValidation.js.map +1 -1
  60. package/build/cjs/common/components/clusterWizard/networkingSteps/NetworkTypeControlGroup.js +3 -3
  61. package/build/cjs/common/components/clusterWizard/networkingSteps/NetworkTypeControlGroup.js.map +1 -1
  62. package/build/cjs/common/components/clusterWizard/networkingSteps/StackTypeControlGroup.js +3 -2
  63. package/build/cjs/common/components/clusterWizard/networkingSteps/StackTypeControlGroup.js.map +1 -1
  64. package/build/cjs/common/components/clusterWizard/networkingSteps/VirtualIPControlGroup.js +2 -1
  65. package/build/cjs/common/components/clusterWizard/networkingSteps/VirtualIPControlGroup.js.map +1 -1
  66. package/build/cjs/common/components/ui/OpenShiftVersionModal.js +1 -3
  67. package/build/cjs/common/components/ui/OpenShiftVersionModal.js.map +1 -1
  68. package/build/cjs/common/components/ui/WizardFooter.js +1 -1
  69. package/build/cjs/common/components/ui/WizardFooter.js.map +1 -1
  70. package/build/cjs/common/components/ui/formik/PullSecretField.js.map +1 -1
  71. package/build/cjs/common/config/constants.js +2 -21
  72. package/build/cjs/common/config/constants.js.map +1 -1
  73. package/build/cjs/common/types/index.js +1 -0
  74. package/build/cjs/common/types/index.js.map +1 -1
  75. package/build/cjs/common/types/networkType.js +28 -0
  76. package/build/cjs/common/types/networkType.js.map +1 -0
  77. package/build/cjs/common/validationSchemas/addressValidation.js +1 -3
  78. package/build/cjs/common/validationSchemas/addressValidation.js.map +1 -1
  79. package/build/cjs/common/validationSchemas/clusterDetailsValidation.js +2 -31
  80. package/build/cjs/common/validationSchemas/clusterDetailsValidation.js.map +1 -1
  81. package/build/cjs/ocm/components/Routes.js +1 -2
  82. package/build/cjs/ocm/components/Routes.js.map +1 -1
  83. package/build/cjs/ocm/components/clusterConfiguration/DiscoveryImageTypeDropdown.js +0 -1
  84. package/build/cjs/ocm/components/clusterConfiguration/DiscoveryImageTypeDropdown.js.map +1 -1
  85. package/build/cjs/ocm/components/clusterConfiguration/OcmDiscoveryImageConfigForm.js +1 -1
  86. package/build/cjs/ocm/components/clusterConfiguration/OcmDiscoveryImageConfigForm.js.map +1 -1
  87. package/build/cjs/ocm/components/clusterConfiguration/manifestsConfiguration/CustomManifestsPage.js +11 -6
  88. package/build/cjs/ocm/components/clusterConfiguration/manifestsConfiguration/CustomManifestsPage.js.map +1 -1
  89. package/build/cjs/ocm/components/clusterConfiguration/manifestsConfiguration/components/CustomManifestsArray.js +4 -1
  90. package/build/cjs/ocm/components/clusterConfiguration/manifestsConfiguration/components/CustomManifestsArray.js.map +1 -1
  91. package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfiguration.js +1 -4
  92. package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfiguration.js.map +1 -1
  93. package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/NetworkTypeDropdown.js +22 -29
  94. package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/NetworkTypeDropdown.js.map +1 -1
  95. package/build/cjs/ocm/components/clusterConfiguration/review/ReviewStep.js +8 -14
  96. package/build/cjs/ocm/components/clusterConfiguration/review/ReviewStep.js.map +1 -1
  97. package/build/cjs/ocm/components/clusterConfiguration/staticIp/commonValidationSchemas.js +2 -5
  98. package/build/cjs/ocm/components/clusterConfiguration/staticIp/commonValidationSchemas.js.map +1 -1
  99. package/build/cjs/ocm/components/clusterConfiguration/staticIp/components/FormViewHosts/FormViewHostsFields.js +1 -1
  100. package/build/cjs/ocm/components/clusterConfiguration/staticIp/components/FormViewHosts/FormViewHostsFields.js.map +1 -1
  101. package/build/cjs/ocm/components/clusterConfiguration/staticIp/components/FormViewNetworkWide/FormViewNetworkWide.js +1 -1
  102. package/build/cjs/ocm/components/clusterConfiguration/staticIp/components/FormViewNetworkWide/FormViewNetworkWide.js.map +1 -1
  103. package/build/cjs/ocm/components/clusterConfiguration/staticIp/components/FormViewNetworkWide/formViewNetworkWideValidationSchema.js +3 -31
  104. package/build/cjs/ocm/components/clusterConfiguration/staticIp/components/FormViewNetworkWide/formViewNetworkWideValidationSchema.js.map +1 -1
  105. package/build/cjs/ocm/components/clusterWizard/ClusterDetails.js +1 -2
  106. package/build/cjs/ocm/components/clusterWizard/ClusterDetails.js.map +1 -1
  107. package/build/cjs/ocm/components/clusterWizard/ClusterDetailsForm.js +1 -2
  108. package/build/cjs/ocm/components/clusterWizard/ClusterDetailsForm.js.map +1 -1
  109. package/build/cjs/ocm/components/clusterWizard/ClusterWizardContext.js.map +1 -1
  110. package/build/cjs/ocm/components/clusterWizard/ClusterWizardContextProvider.js +9 -62
  111. package/build/cjs/ocm/components/clusterWizard/ClusterWizardContextProvider.js.map +1 -1
  112. package/build/cjs/ocm/components/clusterWizard/ClusterWizardFooter.js +6 -21
  113. package/build/cjs/ocm/components/clusterWizard/ClusterWizardFooter.js.map +1 -1
  114. package/build/cjs/ocm/components/clusterWizard/NewClusterWizard.js +1 -11
  115. package/build/cjs/ocm/components/clusterWizard/NewClusterWizard.js.map +1 -1
  116. package/build/cjs/ocm/components/clusterWizard/constants.js +0 -1
  117. package/build/cjs/ocm/components/clusterWizard/constants.js.map +1 -1
  118. package/build/cjs/ocm/components/clusterWizard/disconnected/BasicStep.js +18 -96
  119. package/build/cjs/ocm/components/clusterWizard/disconnected/BasicStep.js.map +1 -1
  120. package/build/cjs/ocm/components/clusterWizard/disconnected/ReviewStep.js +7 -11
  121. package/build/cjs/ocm/components/clusterWizard/disconnected/ReviewStep.js.map +1 -1
  122. package/build/cjs/ocm/components/clusterWizard/index.js +1 -3
  123. package/build/cjs/ocm/components/clusterWizard/index.js.map +1 -1
  124. package/build/cjs/ocm/components/clusterWizard/wizardTransition.js +0 -3
  125. package/build/cjs/ocm/components/clusterWizard/wizardTransition.js.map +1 -1
  126. package/build/cjs/ocm/components/featureSupportLevels/featureStateUtils.js +13 -4
  127. package/build/cjs/ocm/components/featureSupportLevels/featureStateUtils.js.map +1 -1
  128. package/build/cjs/ocm/components/utils.js +1 -4
  129. package/build/cjs/ocm/components/utils.js.map +1 -1
  130. package/build/cjs/ocm/hooks/useInfraEnvId.js +2 -2
  131. package/build/cjs/ocm/hooks/useInfraEnvId.js.map +1 -1
  132. package/build/cjs/ocm/services/ClustersService.js +0 -6
  133. package/build/cjs/ocm/services/ClustersService.js.map +1 -1
  134. package/build/cjs/ocm/services/InfraEnvsService.js +1 -4
  135. package/build/cjs/ocm/services/InfraEnvsService.js.map +1 -1
  136. package/build/cjs/ocm/store/slices/clusters/selectors.js.map +1 -1
  137. package/lib/cim/components/ClusterDeployment/networkConfigurationValidation.ts +1 -1
  138. package/lib/common/api/assisted-service/ClustersAPI.ts +0 -6
  139. package/lib/common/components/clusterWizard/clusterDetailsValidation.ts +9 -19
  140. package/lib/common/components/clusterWizard/networkingSteps/NetworkTypeControlGroup.tsx +1 -1
  141. package/lib/common/components/clusterWizard/networkingSteps/StackTypeControlGroup.tsx +5 -6
  142. package/lib/common/components/clusterWizard/networkingSteps/VirtualIPControlGroup.tsx +2 -2
  143. package/lib/common/components/ui/OpenShiftVersionModal.tsx +1 -3
  144. package/lib/common/components/ui/WizardFooter.tsx +1 -1
  145. package/lib/common/components/ui/formik/PullSecretField.tsx +0 -1
  146. package/lib/common/config/constants.ts +0 -21
  147. package/lib/common/types/index.ts +1 -0
  148. package/lib/common/types/networkType.ts +37 -0
  149. package/lib/common/validationSchemas/addressValidation.tsx +1 -4
  150. package/lib/common/validationSchemas/clusterDetailsValidation.tsx +15 -47
  151. package/lib/ocm/components/Routes.tsx +1 -3
  152. package/lib/ocm/components/clusterConfiguration/DiscoveryImageTypeDropdown.tsx +0 -1
  153. package/lib/ocm/components/clusterConfiguration/OcmDiscoveryImageConfigForm.tsx +3 -2
  154. package/lib/ocm/components/clusterConfiguration/manifestsConfiguration/CustomManifestsPage.tsx +14 -6
  155. package/lib/ocm/components/clusterConfiguration/manifestsConfiguration/components/CustomManifestsArray.tsx +5 -1
  156. package/lib/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfiguration.tsx +0 -5
  157. package/lib/ocm/components/clusterConfiguration/networkConfiguration/NetworkTypeDropdown.tsx +32 -47
  158. package/lib/ocm/components/clusterConfiguration/review/ReviewStep.tsx +10 -12
  159. package/lib/ocm/components/clusterConfiguration/staticIp/commonValidationSchemas.tsx +2 -8
  160. package/lib/ocm/components/clusterConfiguration/staticIp/components/FormViewHosts/FormViewHostsFields.tsx +0 -1
  161. package/lib/ocm/components/clusterConfiguration/staticIp/components/FormViewNetworkWide/FormViewNetworkWide.tsx +2 -2
  162. package/lib/ocm/components/clusterConfiguration/staticIp/components/FormViewNetworkWide/formViewNetworkWideValidationSchema.tsx +24 -63
  163. package/lib/ocm/components/clusterWizard/ClusterDetails.tsx +1 -2
  164. package/lib/ocm/components/clusterWizard/ClusterDetailsForm.tsx +2 -1
  165. package/lib/ocm/components/clusterWizard/ClusterWizardContext.tsx +0 -3
  166. package/lib/ocm/components/clusterWizard/ClusterWizardContextProvider.tsx +27 -91
  167. package/lib/ocm/components/clusterWizard/ClusterWizardFooter.tsx +5 -26
  168. package/lib/ocm/components/clusterWizard/NewClusterWizard.tsx +3 -14
  169. package/lib/ocm/components/clusterWizard/constants.ts +0 -1
  170. package/lib/ocm/components/clusterWizard/disconnected/BasicStep.tsx +37 -138
  171. package/lib/ocm/components/clusterWizard/disconnected/ReviewStep.tsx +9 -19
  172. package/lib/ocm/components/clusterWizard/index.ts +0 -1
  173. package/lib/ocm/components/clusterWizard/wizardTransition.ts +1 -5
  174. package/lib/ocm/components/featureSupportLevels/featureStateUtils.ts +15 -4
  175. package/lib/ocm/components/utils.ts +0 -4
  176. package/lib/ocm/hooks/useInfraEnvId.ts +2 -2
  177. package/lib/ocm/services/ClustersService.ts +0 -6
  178. package/lib/ocm/services/InfraEnvsService.ts +1 -4
  179. package/lib/ocm/store/slices/clusters/selectors.tsx +2 -1
  180. package/package.json +3 -3
  181. package/build/@types/ocm/components/clusterWizard/disconnected/DisconnectedStaticIp.d.ts +0 -4
  182. package/build/@types/ocm/components/clusterWizard/disconnected/DisconnectedStaticIp.d.ts.map +0 -1
  183. package/build/@types/ocm/components/clusterWizard/disconnected/OptionalConfigurationsStep.d.ts +0 -4
  184. package/build/@types/ocm/components/clusterWizard/disconnected/OptionalConfigurationsStep.d.ts.map +0 -1
  185. package/build/cjs/ocm/components/clusterWizard/disconnected/DisconnectedStaticIp.js +0 -48
  186. package/build/cjs/ocm/components/clusterWizard/disconnected/DisconnectedStaticIp.js.map +0 -1
  187. package/build/cjs/ocm/components/clusterWizard/disconnected/OptionalConfigurationsStep.js +0 -182
  188. package/build/cjs/ocm/components/clusterWizard/disconnected/OptionalConfigurationsStep.js.map +0 -1
  189. package/lib/ocm/components/clusterWizard/disconnected/DisconnectedStaticIp.tsx +0 -78
  190. package/lib/ocm/components/clusterWizard/disconnected/OptionalConfigurationsStep.tsx +0 -364
@@ -29,10 +29,7 @@ export const ipNoSuffixValidationSchema = (t: TFunction) =>
29
29
 
30
30
  export const macAddressValidationSchema = (t: TFunction) =>
31
31
  Yup.string().matches(MAC_REGEX, {
32
- message: (params: { value?: unknown }) =>
33
- t('ai:Value "{{value}}" is not valid MAC address.', {
34
- value: params?.value !== undefined ? String(params.value) : '',
35
- }),
32
+ message: (value) => t('ai:Value "{{value}}" is not valid MAC address.', { value }),
36
33
  excludeEmptyString: true,
37
34
  });
38
35
 
@@ -123,55 +123,23 @@ export const dnsNameValidationSchema = (t: TFunction) =>
123
123
  excludeEmptyString: true,
124
124
  });
125
125
 
126
- const MAX_DNS_NAME_LENGTH = 253;
127
- /** Only letters, digits, hyphen, and dot (valid DNS/hostname characters). */
128
- const DNS_CHARS_REGEX = /^[a-z0-9.-]+$/i;
129
-
130
- /**
131
- * Validates the full cluster address [clusterName].[baseDomain] as a single DNS/hostname
132
- * (e.g. "doma.ca" is valid even though "ca" alone might not pass standalone base-domain rules).
133
- */
134
- export const isValidFullClusterAddress = (full: string): boolean => {
135
- if (!full || full === '.' || /\s/.test(full)) {
136
- return false;
137
- }
138
- if (full.length > MAX_DNS_NAME_LENGTH) {
139
- return false;
140
- }
141
- if (!DNS_CHARS_REGEX.test(full)) {
142
- return false;
143
- }
144
- const labels = full.split('.');
145
- if (labels.some((label) => label.length === 0 || label.length > 63)) {
146
- return false;
147
- }
148
- return HOST_NAME_REGEX.test(full);
149
- };
150
-
151
126
  export const baseDomainValidationSchema = (t: TFunction) =>
152
- Yup.string()
153
- .test(
154
- 'dns-name-label-length',
155
- t(
156
- 'ai:Every single host component in the base domain name cannot contain more than 63 characters and must not contain spaces.',
157
- ),
158
- (value?: string) => {
159
- // Check if the value contains any spaces
160
- if (/\s/.test(value as string)) {
161
- return false; // Value contains spaces, validation fails
162
- }
127
+ Yup.string().test(
128
+ 'dns-name-label-length',
129
+ t(
130
+ 'ai:Every single host component in the base domain name cannot contain more than 63 characters and must not contain spaces.',
131
+ ),
132
+ (value?: string) => {
133
+ // Check if the value contains any spaces
134
+ if (/\s/.test(value as string)) {
135
+ return false; // Value contains spaces, validation fails
136
+ }
163
137
 
164
- // Check the label lengths
165
- const labels = (value || '').split('.');
166
- return labels.every((label: string) => label.length <= 63);
167
- },
168
- )
169
- .matches(NAME_CHARS_REGEX, {
170
- message: t(
171
- 'ai:Base domain can only contain letters, digits, hyphens, and dots. Example: example.com',
172
- ),
173
- excludeEmptyString: true,
174
- });
138
+ // Check the label lengths
139
+ const labels = (value || '').split('.');
140
+ return labels.every((label: string) => label.length <= 63);
141
+ },
142
+ );
175
143
 
176
144
  export const locationValidationSchema = (t: TFunction) =>
177
145
  Yup.string()
@@ -34,9 +34,7 @@ export const UILibRoutes = ({
34
34
  <>
35
35
  <Routes>
36
36
  <Route path="assisted-installer/clusters" element={<Outlet />}>
37
- <Route path="~new" element={<NewClusterPage />}>
38
- <Route path=":clusterId" element={<NewClusterPage />} />
39
- </Route>
37
+ <Route path="~new" element={<NewClusterPage />} />
40
38
  <Route path=":clusterId" element={<ClusterPage />} />
41
39
  <Route index element={<Clusters />} />
42
40
  </Route>
@@ -20,7 +20,6 @@ export const discoveryImageTypes: Record<DiscoveryImageType, string> = {
20
20
  'minimal-iso': 'Minimal image file - Download an ISO that fetches content on boot',
21
21
  'full-iso': 'Full image file - Download a self-contained ISO',
22
22
  'discovery-image-ipxe': 'iPXE - Provision from your network server',
23
- 'disconnected-iso': 'Disconnected ISO - Provision from a local file',
24
23
  };
25
24
 
26
25
  type DiscoveryImageTypeDropdownProps = {
@@ -16,6 +16,7 @@ import { Formik, FormikHelpers } from 'formik';
16
16
  import { TFunction } from 'i18next';
17
17
  import {
18
18
  HostStaticNetworkConfig,
19
+ ImageType,
19
20
  InfraEnv,
20
21
  Proxy,
21
22
  } from '@openshift-assisted/types/assisted-installer-service';
@@ -71,7 +72,7 @@ type OcmDiscoveryImageConfigFormProps = Proxy & {
71
72
  formikActions: FormikHelpers<OcmDiscoveryImageFormValues>,
72
73
  ) => Promise<void>;
73
74
  sshPublicKey?: string;
74
- imageType?: DiscoveryImageType;
75
+ imageType?: ImageType;
75
76
  isIpxeSelected?: boolean;
76
77
  enableCertificate?: boolean;
77
78
  trustBundle?: InfraEnv['additionalTrustBundle'];
@@ -105,7 +106,7 @@ export const OcmDiscoveryImageConfigForm = ({
105
106
  httpsProxy: httpsProxy || '',
106
107
  noProxy: noProxy || '',
107
108
  enableProxy: !!(httpProxy || httpsProxy || noProxy),
108
- imageType: imageType,
109
+ imageType: imageTypeValue as ImageType,
109
110
  enableCertificate: enableCertificate || false,
110
111
  trustBundle: trustBundle || '',
111
112
  };
@@ -15,8 +15,9 @@ import {
15
15
  import { CustomManifests } from './components/CustomManifests';
16
16
  import { Cluster } from '@openshift-assisted/types/assisted-installer-service';
17
17
  import { CustomManifestFormState } from './components/propTypes';
18
- import { ClustersAPI, ClusterWizardStepHeader } from '../../../../common';
19
- import { isOciPlatformType, isThirdPartyCNI } from '../../utils';
18
+ import { ClustersAPI, ClusterWizardStepHeader, isThirdPartyCNI } from '../../../../common';
19
+ import { getFieldId } from '../../../../common/components/ui/formik';
20
+ import { isOciPlatformType } from '../../utils';
20
21
  import DeleteCustomManifestModal from './DeleteCustomManifestModal';
21
22
  import { ClustersService } from '../../../services';
22
23
  import { useClusterWizardContext } from '../../clusterWizard/ClusterWizardContext';
@@ -77,9 +78,14 @@ export const CustomManifestsPage = ({
77
78
  await ClustersService.removeClusterManifests(manifests, cluster.id);
78
79
  setUseCustomManifests(false);
79
80
  setDeleteModalOpen(false);
80
- await clusterWizardContext.updateUISettings({ customManifestsAdded: false });
81
+ await clusterWizardContext.updateUISettings({
82
+ customManifestsAdded: false,
83
+ customManifestsUpdated: true,
84
+ });
81
85
  }, [cluster.id, clusterWizardContext]);
82
86
 
87
+ const fieldId = getFieldId('use-custom-manifests', 'switch');
88
+
83
89
  const tooltipWhenDisabled = isRequired
84
90
  ? 'Custom manifests are required when using a third-party CNI or Oracle Cloud Infrastructure.'
85
91
  : '';
@@ -133,11 +139,13 @@ export const CustomManifestsPage = ({
133
139
  configuration of the cluster.
134
140
  </Content>
135
141
  </Content>
136
- <FormGroup fieldId="use-custom-manifests" label="">
142
+ <FormGroup fieldId={fieldId} label="">
137
143
  <Tooltip content={tooltipWhenDisabled} hidden={!isRequired}>
138
144
  <span style={{ display: 'inline-block', cursor: isRequired ? 'not-allowed' : undefined }}>
139
145
  <Switch
140
- id="use-custom-manifests"
146
+ id={fieldId}
147
+ data-testid={fieldId}
148
+ data-checked={useCustomManifests}
141
149
  isChecked={useCustomManifests}
142
150
  isDisabled={isRequired}
143
151
  onChange={handleSwitchChange}
@@ -146,7 +154,7 @@ export const CustomManifestsPage = ({
146
154
  </span>
147
155
  </Tooltip>
148
156
  </FormGroup>
149
- {!useCustomManifests && <div style={{ minHeight: '120px' }} aria-hidden="true" />}
157
+ {!useCustomManifests && <div style={{ minHeight: '250px' }} aria-hidden="true" />}
150
158
  {useCustomManifests && (
151
159
  <>
152
160
  {reminderAlerts}
@@ -12,6 +12,7 @@ import { CustomManifest } from './CustomManifest';
12
12
  import { getEmptyManifest, getManifestName } from './utils';
13
13
  import { CustomManifestValues } from '../data/dataTypes';
14
14
  import { selectCurrentClusterPermissionsState } from '../../../../store/slices/current-cluster/selectors';
15
+ import { useClusterWizardContext } from '../../../clusterWizard/ClusterWizardContext';
15
16
 
16
17
  const fieldName = 'manifests';
17
18
 
@@ -40,6 +41,8 @@ export const CustomManifestsArray = ({
40
41
  clusterId,
41
42
  ...props
42
43
  }: CustomManifestsArrayProps) => {
44
+ const { updateUISettings } = useClusterWizardContext();
45
+
43
46
  const [field, { error }] = useField<CustomManifestValues[]>({
44
47
  name: fieldName,
45
48
  });
@@ -67,6 +70,7 @@ export const CustomManifestsArray = ({
67
70
  manifestToRemove['folder'] as string,
68
71
  manifestToRemove['filename'],
69
72
  );
73
+ await updateUISettings({ customManifestsUpdated: true });
70
74
  } catch (e) {
71
75
  handleApiError(e, () =>
72
76
  addAlert({
@@ -77,7 +81,7 @@ export const CustomManifestsArray = ({
77
81
  }
78
82
  }
79
83
  },
80
- [addAlert, field.value],
84
+ [addAlert, field.value, updateUISettings],
81
85
  );
82
86
 
83
87
  const onConfirm = React.useCallback(async (): Promise<void> => {
@@ -4,7 +4,6 @@ import { useSelector } from 'react-redux';
4
4
  import { Stack, StackItem, Tooltip } from '@patternfly/react-core';
5
5
  import {
6
6
  canBeDualStack,
7
- canSelectNetworkTypeSDN,
8
7
  CpuArchitecture,
9
8
  DUAL_STACK,
10
9
  HostSubnets,
@@ -144,9 +143,6 @@ const NetworkConfiguration = ({
144
143
  const isDualStack = values.stackType === DUAL_STACK;
145
144
 
146
145
  const isDualStackSelectable = React.useMemo(() => canBeDualStack(hostSubnets), [hostSubnets]);
147
- const isSDNSelectable = React.useMemo(() => {
148
- return canSelectNetworkTypeSDN(isSNOCluster, isDualStack);
149
- }, [isSNOCluster, isDualStack]);
150
146
 
151
147
  const [isAdvanced, setAdvanced] = React.useState(
152
148
  isDualStack || isAdvNetworkConf(cluster, defaultNetworkSettings),
@@ -262,7 +258,6 @@ const NetworkConfiguration = ({
262
258
  <StackItem>
263
259
  <NetworkTypeDropDown
264
260
  isDisabled={isViewerMode}
265
- isSDNSelectable={isSDNSelectable}
266
261
  featureSupportLevelData={featureSupportLevelData}
267
262
  />
268
263
  </StackItem>
@@ -12,82 +12,71 @@ import {
12
12
  StackItem,
13
13
  Tooltip,
14
14
  } from '@patternfly/react-core';
15
- import {
16
- NETWORK_TYPE_CALICO,
17
- NETWORK_TYPE_CILIUM,
18
- NETWORK_TYPE_CISCO_ACI,
19
- NETWORK_TYPE_LABELS,
20
- NETWORK_TYPE_NONE,
21
- NETWORK_TYPE_OVN,
22
- NETWORK_TYPE_SDN,
23
- } from '../../../../common/config';
24
15
  import { getFieldId, ExternalLink } from '../../../../common/components/ui';
25
16
  import {
26
17
  NewFeatureSupportLevelMap,
27
18
  useNewFeatureSupportLevel,
28
19
  } from '../../../../common/components/newFeatureSupportLevels';
29
- import { TechnologyPreview } from '../../../../common/components/ui/TechnologyPreview';
20
+ import NewFeatureSupportLevelBadge from '../../../../common/components/newFeatureSupportLevels/NewFeatureSupportLevelBadge';
30
21
  import type { NetworkConfigurationValues } from '../../../../common/types/clusters';
31
- import { isThirdPartyCNI } from '../../utils';
22
+ import {
23
+ NETWORK_TYPE_OVN,
24
+ NETWORK_TYPE_LABELS,
25
+ NETWORK_TYPE_FEATURE_IDS,
26
+ isThirdPartyCNI,
27
+ } from '../../../../common/types/networkType';
32
28
  import { RED_HAT_CNI_SUPPORT_MATRIX_LINK } from '../../../../common/config/docs_links';
33
29
 
34
30
  export interface NetworkTypeDropDownProps {
35
31
  isDisabled?: boolean;
36
- isSDNSelectable: boolean;
37
32
  featureSupportLevelData: NewFeatureSupportLevelMap | null;
38
33
  }
39
34
 
40
35
  export const NetworkTypeDropDown = ({
41
36
  isDisabled = false,
42
- isSDNSelectable,
43
37
  featureSupportLevelData,
44
38
  }: NetworkTypeDropDownProps) => {
45
39
  const [field, , { setValue }] = useField<string>('networkType');
46
40
  const [isOpen, setOpen] = React.useState(false);
47
41
  const { values } = useFormikContext<NetworkConfigurationValues>();
48
- const { getFeatureDisabledReason } = useNewFeatureSupportLevel();
42
+ const { getFeatureDisabledReason, getFeatureSupportLevel } = useNewFeatureSupportLevel();
49
43
  const fieldId = getFieldId('networkType', 'input');
50
44
  const showThirdPartyBanner = isThirdPartyCNI(values.networkType);
51
45
 
52
- const sdnDisabledReason = React.useMemo(() => {
53
- if (!isSDNSelectable) {
54
- return 'SDN is not supported for SNO clusters or when IPv6 is detected.';
55
- }
56
- return getFeatureDisabledReason('SDN_NETWORK_TYPE', featureSupportLevelData ?? undefined);
57
- }, [isSDNSelectable, featureSupportLevelData, getFeatureDisabledReason]);
58
-
59
46
  React.useEffect(() => {
60
- if (field.value === NETWORK_TYPE_SDN && sdnDisabledReason) {
47
+ if (
48
+ getFeatureDisabledReason(
49
+ NETWORK_TYPE_FEATURE_IDS[field.value],
50
+ featureSupportLevelData ?? undefined,
51
+ ) !== undefined
52
+ ) {
61
53
  setValue(NETWORK_TYPE_OVN);
62
54
  }
63
- }, [sdnDisabledReason, field.value, setValue]);
55
+ }, [field.value, setValue, featureSupportLevelData, getFeatureDisabledReason]);
64
56
 
65
57
  const currentDisplayValue = NETWORK_TYPE_LABELS[field.value];
66
58
 
67
59
  const dropdownItems = Object.entries(NETWORK_TYPE_LABELS).map(([value, label]) => {
68
- const isSDN = value === NETWORK_TYPE_SDN;
69
- const disabledReason = isSDN ? sdnDisabledReason : undefined;
70
- const isTechPreview = [
71
- NETWORK_TYPE_CISCO_ACI,
72
- NETWORK_TYPE_CILIUM,
73
- NETWORK_TYPE_CALICO,
74
- NETWORK_TYPE_NONE,
75
- ].includes(value);
60
+ const disabledReason = getFeatureDisabledReason(
61
+ NETWORK_TYPE_FEATURE_IDS[value],
62
+ featureSupportLevelData ?? undefined,
63
+ );
64
+ const featureId = NETWORK_TYPE_FEATURE_IDS[value];
65
+ const supportLevel = featureId
66
+ ? getFeatureSupportLevel(featureId, featureSupportLevelData ?? undefined)
67
+ : undefined;
68
+ const shouldDisable =
69
+ supportLevel === 'unavailable' ||
70
+ supportLevel === 'unsupported' ||
71
+ disabledReason !== undefined;
76
72
  return (
77
- <DropdownItem
78
- key={value}
79
- id={value}
80
- value={value}
81
- isAriaDisabled={disabledReason !== undefined}
82
- >
73
+ <DropdownItem key={value} id={value} value={value} isAriaDisabled={shouldDisable}>
83
74
  <Tooltip hidden={!disabledReason} content={disabledReason} position="top">
84
75
  <div>
85
76
  {label}
86
- {isTechPreview && (
87
- <span onClick={(event) => event.stopPropagation()}>
88
- <TechnologyPreview testId={`${value}-support-level`} />
89
- </span>
90
- )}
77
+ <span onClick={(event) => event.stopPropagation()}>
78
+ <NewFeatureSupportLevelBadge featureId={featureId} supportLevel={supportLevel} />
79
+ </span>
91
80
  </div>
92
81
  </Tooltip>
93
82
  </DropdownItem>
@@ -132,11 +121,7 @@ export const NetworkTypeDropDown = ({
132
121
  </StackItem>
133
122
  {showThirdPartyBanner && (
134
123
  <StackItem>
135
- <Alert
136
- variant={AlertVariant.warning}
137
- isInline
138
- title="Third-party CNI (Technology Preview)"
139
- >
124
+ <Alert variant={AlertVariant.warning} isInline title="Third-party CNI">
140
125
  <Stack hasGutter>
141
126
  <StackItem>
142
127
  Third-party CNIs require uploading CNI manifests. Please verify you have the
@@ -24,19 +24,17 @@ const ReviewStep = ({ cluster }: { cluster: Cluster }) => {
24
24
  const [disableInstallButton, setDisableInstallButton] = React.useState<boolean>();
25
25
 
26
26
  React.useEffect(() => {
27
- if (
27
+ const manifestFail =
28
28
  cluster['last-installation-preparation']?.status === 'failed' &&
29
- cluster['last-installation-preparation'].reason?.includes('manifest')
30
- ) {
31
- if (clusterWizardContext.uiSettings?.customManifestsUpdated === undefined) {
32
- setDisableInstallButton(true);
33
- void clusterWizardContext.updateUISettings({ customManifestsUpdated: false });
34
- } else if (clusterWizardContext.uiSettings?.customManifestsUpdated === false) {
35
- setDisableInstallButton(true);
36
- }
37
- } else {
38
- setDisableInstallButton(isViewerMode || isStartingInstallation || cluster.status !== 'ready');
39
- }
29
+ cluster['last-installation-preparation'].reason?.includes('manifest');
30
+ const userDidntAddressManifestIssue =
31
+ clusterWizardContext.uiSettings?.customManifestsUpdated !== true;
32
+ setDisableInstallButton(
33
+ (manifestFail && userDidntAddressManifestIssue) ||
34
+ isViewerMode ||
35
+ isStartingInstallation ||
36
+ cluster.status !== 'ready',
37
+ );
40
38
  }, [cluster, isStartingInstallation, isViewerMode, clusterWizardContext]);
41
39
 
42
40
  const handleClusterInstall = async () => {
@@ -92,17 +92,11 @@ export const getIpAddressValidationSchema = (protocolVersion: ProtocolVersion) =
92
92
  const protocolVersionLabel = protocolVersion === ProtocolVersion.ipv4 ? 'IPv4' : 'IPv6';
93
93
  return Yup.string().test(
94
94
  protocolVersion,
95
- (params: { value?: unknown }) =>
96
- `Value "${
97
- params?.value !== undefined ? String(params.value) : ''
98
- }" is not a valid ${protocolVersionLabel} address`,
95
+ `Value \${value} is not a valid ${protocolVersionLabel} address`,
99
96
  (value?: string) => {
100
- if (value === undefined || value === '') {
97
+ if (!value) {
101
98
  return true;
102
99
  }
103
- if (typeof value !== 'string') {
104
- return false;
105
- }
106
100
  return isValidAddress(value, protocolVersion);
107
101
  },
108
102
  );
@@ -96,7 +96,6 @@ const getExpandedHostComponent = (protocolType: StaticProtocolType) => {
96
96
  label={`IP address (${getProtocolVersionLabel(protocolVersion)})`}
97
97
  fieldId={getFieldId(`${fieldName}.ips.${protocolVersion}`, 'input')}
98
98
  key={protocolVersion}
99
- isRequired
100
99
  >
101
100
  <OcmInputField
102
101
  name={`${fieldName}.ips.${protocolVersion}`}
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import { StaticIpForm } from '../StaticIpForm';
3
3
  import { StaticIpFormProps, StaticIpViewProps } from '../propTypes';
4
4
  import { FormViewHost, FormViewNetworkWideValues } from '../../data/dataTypes';
5
- import { getNetworkWideValidationSchema } from './formViewNetworkWideValidationSchema';
5
+ import { networkWideValidationSchema } from './formViewNetworkWideValidationSchema';
6
6
  import { networkWideToInfraEnvField } from '../../data/formDataToInfraEnvField';
7
7
  import { FormViewNetworkWideFields } from './FormViewNetworkWideFields';
8
8
  import { getFormData, getFormViewNetworkWideValues } from '../../data/fromInfraEnv';
@@ -22,7 +22,7 @@ export const FormViewNetworkWide: React.FC<StaticIpViewProps> = ({ infraEnv, ...
22
22
  setFormProps({
23
23
  infraEnv,
24
24
  ...props,
25
- validationSchema: getNetworkWideValidationSchema(infraEnv.rendezvousIp),
25
+ validationSchema: networkWideValidationSchema,
26
26
  getInitialValues: (infraEnv: InfraEnv) => {
27
27
  return getFormViewNetworkWideValues(infraEnv);
28
28
  },
@@ -95,71 +95,32 @@ const getAddressDataValidationSchema = (protocolVersion: ProtocolVersion, ipConf
95
95
  });
96
96
  };
97
97
 
98
- /**
99
- * Validates that Rendezvous IP (when set) is within the IPv4 subnet.
100
- * Default gateway is already validated by getAddressDataValidationSchema (getInMachineNetworkValidationSchema).
101
- */
102
- const getRendezvousIpCoherenceTest = (rendezvousIp: string | undefined) => {
103
- return Yup.object().test(
104
- 'rendezvous-ip-in-subnet',
105
- 'Rendezvous IP must be within the IPv4 subnet.',
106
- (value: unknown, context: Yup.TestContext) => {
107
- const values = value as FormViewNetworkWideValues | undefined;
108
- const machineNetwork = values?.ipConfigs?.ipv4?.machineNetwork;
109
- if (
110
- !rendezvousIp?.trim() ||
111
- !machineNetwork?.ip?.trim() ||
112
- machineNetwork.prefixLength === '' ||
113
- typeof machineNetwork.prefixLength !== 'number'
114
- ) {
115
- return true;
116
- }
117
- const inSubnetSchema = getInMachineNetworkValidationSchema(
118
- ProtocolVersion.ipv4,
119
- machineNetwork,
120
- );
121
- if (!inSubnetSchema.isValidSync(rendezvousIp)) {
122
- return context.createError({
123
- path: 'ipConfigs.ipv4.machineNetwork.ip',
124
- message: 'Rendezvous IP must be within the IPv4 subnet.',
125
- });
126
- }
127
- return true;
128
- },
129
- );
130
- };
131
-
132
- export const getNetworkWideValidationSchema = (rendezvousIp?: string) =>
133
- Yup.lazy((values: FormViewNetworkWideValues) => {
134
- const ipConfigsValidationSchemas = Yup.object({
135
- ipv4: getAddressDataValidationSchema(ProtocolVersion.ipv4, values.ipConfigs.ipv4),
136
- ipv6: showProtocolVersion(values.protocolType, ProtocolVersion.ipv6)
137
- ? getAddressDataValidationSchema(ProtocolVersion.ipv6, values.ipConfigs.ipv6)
138
- : Yup.object<IpConfig>(),
139
- });
140
-
141
- const baseSchema = Yup.object({
142
- useVlan: Yup.boolean(),
143
- vlanId: Yup.mixed().when('useVlan', {
144
- is: (useVlan: boolean) => useVlan,
145
- then: () =>
146
- Yup.number()
147
- .required(MUST_BE_A_NUMBER)
148
- .min(1, `Must be more than or equal to 1`)
149
- .max(MAX_VLAN_ID, `Must be less than or equal to ${MAX_VLAN_ID}`)
150
- .test('not-number', MUST_BE_A_NUMBER, () => validateNumber(values.vlanId))
151
- .nullable()
152
- .transform(transformNumber) as Yup.NumberSchema,
153
- }),
154
- protocolType: Yup.string(),
155
- dns: getDNSValidationSchema(values.protocolType),
156
- ipConfigs: ipConfigsValidationSchemas,
157
- });
158
-
159
- return baseSchema.concat(getRendezvousIpCoherenceTest(rendezvousIp));
98
+ export const networkWideValidationSchema = Yup.lazy((values: FormViewNetworkWideValues) => {
99
+ const ipConfigsValidationSchemas = Yup.object({
100
+ ipv4: getAddressDataValidationSchema(ProtocolVersion.ipv4, values.ipConfigs.ipv4),
101
+ ipv6: showProtocolVersion(values.protocolType, ProtocolVersion.ipv6)
102
+ ? getAddressDataValidationSchema(ProtocolVersion.ipv6, values.ipConfigs.ipv6)
103
+ : Yup.object<IpConfig>(),
160
104
  });
161
105
 
162
- export const networkWideValidationSchema = getNetworkWideValidationSchema();
106
+ return Yup.object({
107
+ useVlan: Yup.boolean(),
108
+ vlanId: Yup.mixed().when('useVlan', {
109
+ is: (useVlan: boolean) => useVlan,
110
+ then: () =>
111
+ Yup.number()
112
+ .required(MUST_BE_A_NUMBER)
113
+ .min(1, `Must be more than or equal to 1`)
114
+ .max(MAX_VLAN_ID, `Must be less than or equal to ${MAX_VLAN_ID}`)
115
+ .test('not-number', MUST_BE_A_NUMBER, () => validateNumber(values.vlanId))
116
+ .nullable()
117
+ .transform(transformNumber) as Yup.NumberSchema,
118
+ }),
119
+ protocolType: Yup.string(),
120
+ dns: getDNSValidationSchema(values.protocolType),
121
+ ipConfigs: ipConfigsValidationSchemas,
122
+ });
123
+ });
163
124
 
164
125
  export const validateNumber = (vlanId: FormViewNetworkWideValues['vlanId']) => {
165
126
  //We need to validate that value is a number(without letters) and is not an exponential number (ex: 1e2)
@@ -39,6 +39,7 @@ const ClusterDetails = ({ cluster, infraEnv }: ClusterDetailsProps) => {
39
39
  const navigate = useNavigate();
40
40
  const dispatch = useDispatch();
41
41
  const { usedClusterNames } = useUsedClusterNames(cluster?.id || '');
42
+ const pullSecret = usePullSecret();
42
43
  const {
43
44
  error: errorOCPVersions,
44
45
  loading: loadingOCPVersions,
@@ -46,8 +47,6 @@ const ClusterDetails = ({ cluster, infraEnv }: ClusterDetailsProps) => {
46
47
  } = useOpenShiftVersionsContext();
47
48
  const location = useLocation();
48
49
  const isSingleClusterFeatureEnabled = useFeature('ASSISTED_INSTALLER_SINGLE_CLUSTER_FEATURE');
49
- const defaultPullSecret = usePullSecret();
50
- const pullSecret = isSingleClusterFeatureEnabled ? infraEnv?.pullSecret || '' : defaultPullSecret;
51
50
 
52
51
  const handleClusterUpdate = React.useCallback(
53
52
  async (clusterId: Cluster['id'], params: ClusterDetailsUpdateParams) => {
@@ -11,9 +11,10 @@ import {
11
11
  getRichTextValidation,
12
12
  useAlerts,
13
13
  TechnologyPreview,
14
+ OpenshiftVersionOptionType,
15
+ getFormikErrorFields,
14
16
  } from '../../../common';
15
17
  import { canNextClusterDetails } from './wizardTransition';
16
- import { OpenshiftVersionOptionType, getFormikErrorFields } from '../../../common';
17
18
  import ClusterWizardFooter from './ClusterWizardFooter';
18
19
  import { isInOcm } from '../../../common/api';
19
20
  import {
@@ -3,7 +3,6 @@ import { HostsNetworkConfigurationType } from '../../services';
3
3
  import { StaticIpView } from '../clusterConfiguration/staticIp/data/dataTypes';
4
4
  import { ClusterWizardStepsType } from './wizardTransition';
5
5
  import { UISettingsValues } from '../../../common';
6
- import { InfraEnv } from '@openshift-assisted/types/assisted-installer-service';
7
6
 
8
7
  export type ClusterWizardContextType = {
9
8
  currentStepId: ClusterWizardStepsType;
@@ -19,8 +18,6 @@ export type ClusterWizardContextType = {
19
18
  uiSettings?: UISettingsValues;
20
19
  installDisconnected: boolean;
21
20
  setInstallDisconnected: (enabled: boolean) => void;
22
- disconnectedInfraEnv?: InfraEnv;
23
- setDisconnectedInfraEnv: (infraEnv: InfraEnv | undefined) => void;
24
21
  };
25
22
 
26
23
  export const ClusterWizardContext = React.createContext<ClusterWizardContextType | null>(null);