@openshift-assisted/ui-lib 2.17.1-cim → 2.17.3-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 (208) hide show
  1. package/build/@types/cim/components/ClusterDeployment/clusterDetails/ClusterDeploymentDetailsForm.d.ts.map +1 -1
  2. package/build/@types/cim/components/ClusterDeployment/clusterDetails/ClusterDetailsFormFields.d.ts +0 -1
  3. package/build/@types/cim/components/ClusterDeployment/clusterDetails/ClusterDetailsFormFields.d.ts.map +1 -1
  4. package/build/@types/cim/components/ClusterDeployment/hostSelection/ClusterDeploymentHostSelectionStep.d.ts.map +1 -1
  5. package/build/@types/cim/components/ClusterDeployment/use-networking-formik.d.ts.map +1 -1
  6. package/build/@types/cim/components/Hypershift/HostedClusterWizard/HostsStep/HostsStep.d.ts.map +1 -1
  7. package/build/@types/cim/components/InfraEnv/InfraEnvFormPage.d.ts.map +1 -1
  8. package/build/@types/cim/components/helpers/versions.d.ts +1 -1
  9. package/build/@types/cim/components/helpers/versions.d.ts.map +1 -1
  10. package/build/@types/cim/components/modals/CimConfiguration/CimConfigurationModal.d.ts.map +1 -1
  11. package/build/@types/cim/components/modals/EditProxyModal.d.ts.map +1 -1
  12. package/build/@types/cim/components/modals/EditSSHKeyModal.d.ts.map +1 -1
  13. package/build/@types/common/components/clusterConfiguration/DiscoveryImageConfigForm.d.ts.map +1 -1
  14. package/build/@types/common/components/clusterWizard/clusterDetailsValidation.d.ts.map +1 -1
  15. package/build/@types/common/components/hosts/AdditionalNTPSourcesDialog.d.ts.map +1 -1
  16. package/build/@types/common/components/hosts/EditHostForm.d.ts.map +1 -1
  17. package/build/@types/common/components/hosts/MassChangeHostnameModal.d.ts.map +1 -1
  18. package/build/@types/common/components/ui/formik/index.d.ts +0 -2
  19. package/build/@types/common/components/ui/formik/index.d.ts.map +1 -1
  20. package/build/@types/common/index.d.ts +1 -0
  21. package/build/@types/common/index.d.ts.map +1 -1
  22. package/build/@types/common/utils.d.ts +2 -2
  23. package/build/@types/common/utils.d.ts.map +1 -1
  24. package/build/@types/common/validationSchemas/addressValidation.d.ts +18 -0
  25. package/build/@types/common/validationSchemas/addressValidation.d.ts.map +1 -0
  26. package/build/@types/common/validationSchemas/clusterDetailsValidation.d.ts +8 -0
  27. package/build/@types/common/validationSchemas/clusterDetailsValidation.d.ts.map +1 -0
  28. package/build/@types/common/{components/ui/formik → validationSchemas}/constants.d.ts +1 -3
  29. package/build/@types/common/validationSchemas/constants.d.ts.map +1 -0
  30. package/build/@types/common/validationSchemas/hostnameValidation.d.ts +4 -0
  31. package/build/@types/common/validationSchemas/hostnameValidation.d.ts.map +1 -0
  32. package/build/@types/common/validationSchemas/index.d.ts +11 -0
  33. package/build/@types/common/validationSchemas/index.d.ts.map +1 -0
  34. package/build/@types/common/validationSchemas/networkingValidation.d.ts +18 -0
  35. package/build/@types/common/validationSchemas/networkingValidation.d.ts.map +1 -0
  36. package/build/@types/common/validationSchemas/ntpValidation.d.ts +4 -0
  37. package/build/@types/common/validationSchemas/ntpValidation.d.ts.map +1 -0
  38. package/build/@types/common/validationSchemas/proxyValidation.d.ts +11 -0
  39. package/build/@types/common/validationSchemas/proxyValidation.d.ts.map +1 -0
  40. package/build/@types/common/validationSchemas/pullSecretValidation.d.ts +4 -0
  41. package/build/@types/common/validationSchemas/pullSecretValidation.d.ts.map +1 -0
  42. package/build/@types/common/validationSchemas/regexes.d.ts +14 -0
  43. package/build/@types/common/validationSchemas/regexes.d.ts.map +1 -0
  44. package/build/@types/common/validationSchemas/sshValidation.d.ts +5 -0
  45. package/build/@types/common/validationSchemas/sshValidation.d.ts.map +1 -0
  46. package/build/@types/common/validationSchemas/utils.d.ts +7 -0
  47. package/build/@types/common/validationSchemas/utils.d.ts.map +1 -0
  48. package/build/@types/ocm/components/clusterConfiguration/OcmDiscoveryImageConfigForm.d.ts.map +1 -1
  49. package/build/@types/ocm/components/clusterConfiguration/manifestsConfiguration/components/CustomManifests.d.ts.map +1 -1
  50. package/build/@types/ocm/components/clusterConfiguration/manifestsConfiguration/components/customManifestsValidationSchema.d.ts +2 -1
  51. package/build/@types/ocm/components/clusterConfiguration/manifestsConfiguration/components/customManifestsValidationSchema.d.ts.map +1 -1
  52. package/build/@types/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfigurationForm.d.ts.map +1 -1
  53. package/build/@types/ocm/components/clusterConfiguration/networkConfiguration/networkConfigurationValidation.d.ts +2 -1
  54. package/build/@types/ocm/components/clusterConfiguration/networkConfiguration/networkConfigurationValidation.d.ts.map +1 -1
  55. package/build/@types/ocm/components/clusterConfiguration/staticIp/components/FormViewHosts/FormViewHosts.d.ts.map +1 -1
  56. package/build/@types/ocm/components/clusterConfiguration/staticIp/components/FormViewHosts/formViewHostsValidationSchema.d.ts +2 -1
  57. package/build/@types/ocm/components/clusterConfiguration/staticIp/components/FormViewHosts/formViewHostsValidationSchema.d.ts.map +1 -1
  58. package/build/@types/ocm/components/clusterConfiguration/staticIp/components/YamlView/YamlView.d.ts.map +1 -1
  59. package/build/@types/ocm/components/clusterConfiguration/staticIp/components/YamlView/yamlViewValidationSchema.d.ts +2 -1
  60. package/build/@types/ocm/components/clusterConfiguration/staticIp/components/YamlView/yamlViewValidationSchema.d.ts.map +1 -1
  61. package/build/@types/ocm/components/clusterWizard/disconnected/OptionalConfigurationsStep.d.ts.map +1 -1
  62. package/build/@types/ocm/components/hosts/UpdateDay2ApiVipForm.d.ts.map +1 -1
  63. package/build/cjs/cim/components/Agent/BMCForm.js +3 -3
  64. package/build/cjs/cim/components/Agent/BMCForm.js.map +1 -1
  65. package/build/cjs/cim/components/ClusterDeployment/clusterDetails/ClusterDeploymentDetailsForm.js +9 -15
  66. package/build/cjs/cim/components/ClusterDeployment/clusterDetails/ClusterDeploymentDetailsForm.js.map +1 -1
  67. package/build/cjs/cim/components/ClusterDeployment/clusterDetails/ClusterDetailsFormFields.js +8 -6
  68. package/build/cjs/cim/components/ClusterDeployment/clusterDetails/ClusterDetailsFormFields.js.map +1 -1
  69. package/build/cjs/cim/components/ClusterDeployment/hostSelection/ClusterDeploymentHostSelectionStep.js +1 -3
  70. package/build/cjs/cim/components/ClusterDeployment/hostSelection/ClusterDeploymentHostSelectionStep.js.map +1 -1
  71. package/build/cjs/cim/components/ClusterDeployment/use-networking-formik.js +16 -15
  72. package/build/cjs/cim/components/ClusterDeployment/use-networking-formik.js.map +1 -1
  73. package/build/cjs/cim/components/Hypershift/HostedClusterWizard/DetailsStep/DetailsStep.js +2 -2
  74. package/build/cjs/cim/components/Hypershift/HostedClusterWizard/DetailsStep/DetailsStep.js.map +1 -1
  75. package/build/cjs/cim/components/Hypershift/HostedClusterWizard/HostsStep/HostsStep.js +2 -11
  76. package/build/cjs/cim/components/Hypershift/HostedClusterWizard/HostsStep/HostsStep.js.map +1 -1
  77. package/build/cjs/cim/components/Hypershift/HostedClusterWizard/NetworkStep/NetworkStep.js +8 -8
  78. package/build/cjs/cim/components/Hypershift/HostedClusterWizard/NetworkStep/NetworkStep.js.map +1 -1
  79. package/build/cjs/cim/components/InfraEnv/InfraEnvFormPage.js +8 -6
  80. package/build/cjs/cim/components/InfraEnv/InfraEnvFormPage.js.map +1 -1
  81. package/build/cjs/cim/components/helpers/versions.js +42 -27
  82. package/build/cjs/cim/components/helpers/versions.js.map +1 -1
  83. package/build/cjs/cim/components/modals/CimConfiguration/CimConfigurationModal.js +9 -3
  84. package/build/cjs/cim/components/modals/CimConfiguration/CimConfigurationModal.js.map +1 -1
  85. package/build/cjs/cim/components/modals/EditProxyModal.js +5 -3
  86. package/build/cjs/cim/components/modals/EditProxyModal.js.map +1 -1
  87. package/build/cjs/cim/components/modals/EditPullSecretModal.js +1 -1
  88. package/build/cjs/cim/components/modals/EditPullSecretModal.js.map +1 -1
  89. package/build/cjs/cim/components/modals/EditSSHKeyModal.js +3 -3
  90. package/build/cjs/cim/components/modals/EditSSHKeyModal.js.map +1 -1
  91. package/build/cjs/common/components/clusterConfiguration/DiscoveryImageConfigForm.js +7 -6
  92. package/build/cjs/common/components/clusterConfiguration/DiscoveryImageConfigForm.js.map +1 -1
  93. package/build/cjs/common/components/clusterWizard/clusterDetailsValidation.js +8 -8
  94. package/build/cjs/common/components/clusterWizard/clusterDetailsValidation.js.map +1 -1
  95. package/build/cjs/common/components/hosts/AdditionalNTPSourcesDialog.js +2 -1
  96. package/build/cjs/common/components/hosts/AdditionalNTPSourcesDialog.js.map +1 -1
  97. package/build/cjs/common/components/hosts/EditHostForm.js +3 -2
  98. package/build/cjs/common/components/hosts/EditHostForm.js.map +1 -1
  99. package/build/cjs/common/components/hosts/MassChangeHostnameModal.js +6 -5
  100. package/build/cjs/common/components/hosts/MassChangeHostnameModal.js.map +1 -1
  101. package/build/cjs/common/components/ui/formik/index.js +0 -2
  102. package/build/cjs/common/components/ui/formik/index.js.map +1 -1
  103. package/build/cjs/common/config/docs_links.js +1 -1
  104. package/build/cjs/common/index.js +1 -0
  105. package/build/cjs/common/index.js.map +1 -1
  106. package/build/cjs/common/utils.js +5 -3
  107. package/build/cjs/common/utils.js.map +1 -1
  108. package/build/cjs/common/validationSchemas/addressValidation.js +246 -0
  109. package/build/cjs/common/validationSchemas/addressValidation.js.map +1 -0
  110. package/build/cjs/common/validationSchemas/clusterDetailsValidation.js +104 -0
  111. package/build/cjs/common/validationSchemas/clusterDetailsValidation.js.map +1 -0
  112. package/build/cjs/common/{components/ui/formik → validationSchemas}/constants.js +3 -5
  113. package/build/cjs/common/validationSchemas/constants.js.map +1 -0
  114. package/build/cjs/common/validationSchemas/hostnameValidation.js +36 -0
  115. package/build/cjs/common/validationSchemas/hostnameValidation.js.map +1 -0
  116. package/build/cjs/common/validationSchemas/index.js +17 -0
  117. package/build/cjs/common/validationSchemas/index.js.map +1 -0
  118. package/build/cjs/common/validationSchemas/networkingValidation.js +74 -0
  119. package/build/cjs/common/validationSchemas/networkingValidation.js.map +1 -0
  120. package/build/cjs/common/validationSchemas/ntpValidation.js +25 -0
  121. package/build/cjs/common/validationSchemas/ntpValidation.js.map +1 -0
  122. package/build/cjs/common/validationSchemas/proxyValidation.js +43 -0
  123. package/build/cjs/common/validationSchemas/proxyValidation.js.map +1 -0
  124. package/build/cjs/common/validationSchemas/pullSecretValidation.js +21 -0
  125. package/build/cjs/common/validationSchemas/pullSecretValidation.js.map +1 -0
  126. package/build/cjs/common/validationSchemas/regexes.js +17 -0
  127. package/build/cjs/common/validationSchemas/regexes.js.map +1 -0
  128. package/build/cjs/common/validationSchemas/sshValidation.js +32 -0
  129. package/build/cjs/common/validationSchemas/sshValidation.js.map +1 -0
  130. package/build/cjs/common/validationSchemas/utils.js +40 -0
  131. package/build/cjs/common/validationSchemas/utils.js.map +1 -0
  132. package/build/cjs/ocm/components/clusterConfiguration/OcmDiscoveryImageConfigForm.js +7 -6
  133. package/build/cjs/ocm/components/clusterConfiguration/OcmDiscoveryImageConfigForm.js.map +1 -1
  134. package/build/cjs/ocm/components/clusterConfiguration/manifestsConfiguration/components/CustomManifests.js +4 -2
  135. package/build/cjs/ocm/components/clusterConfiguration/manifestsConfiguration/components/CustomManifests.js.map +1 -1
  136. package/build/cjs/ocm/components/clusterConfiguration/manifestsConfiguration/components/customManifestsValidationSchema.js +7 -6
  137. package/build/cjs/ocm/components/clusterConfiguration/manifestsConfiguration/components/customManifestsValidationSchema.js.map +1 -1
  138. package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfigurationForm.js +2 -1
  139. package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfigurationForm.js.map +1 -1
  140. package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/networkConfigurationValidation.js +11 -11
  141. package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/networkConfigurationValidation.js.map +1 -1
  142. package/build/cjs/ocm/components/clusterConfiguration/staticIp/components/FormViewHosts/FormViewHosts.js +3 -1
  143. package/build/cjs/ocm/components/clusterConfiguration/staticIp/components/FormViewHosts/FormViewHosts.js.map +1 -1
  144. package/build/cjs/ocm/components/clusterConfiguration/staticIp/components/FormViewHosts/formViewHostsValidationSchema.js +6 -6
  145. package/build/cjs/ocm/components/clusterConfiguration/staticIp/components/FormViewHosts/formViewHostsValidationSchema.js.map +1 -1
  146. package/build/cjs/ocm/components/clusterConfiguration/staticIp/components/YamlView/YamlView.js +3 -1
  147. package/build/cjs/ocm/components/clusterConfiguration/staticIp/components/YamlView/YamlView.js.map +1 -1
  148. package/build/cjs/ocm/components/clusterConfiguration/staticIp/components/YamlView/yamlViewValidationSchema.js +12 -12
  149. package/build/cjs/ocm/components/clusterConfiguration/staticIp/components/YamlView/yamlViewValidationSchema.js.map +1 -1
  150. package/build/cjs/ocm/components/clusterWizard/disconnected/OptionalConfigurationsStep.js +4 -3
  151. package/build/cjs/ocm/components/clusterWizard/disconnected/OptionalConfigurationsStep.js.map +1 -1
  152. package/build/cjs/ocm/components/hosts/UpdateDay2ApiVipForm.js +2 -1
  153. package/build/cjs/ocm/components/hosts/UpdateDay2ApiVipForm.js.map +1 -1
  154. package/lib/cim/components/Agent/BMCForm.tsx +3 -3
  155. package/lib/cim/components/ClusterDeployment/clusterDetails/ClusterDeploymentDetailsForm.tsx +8 -18
  156. package/lib/cim/components/ClusterDeployment/clusterDetails/ClusterDetailsFormFields.tsx +7 -10
  157. package/lib/cim/components/ClusterDeployment/hostSelection/ClusterDeploymentHostSelectionStep.tsx +1 -3
  158. package/lib/cim/components/ClusterDeployment/use-networking-formik.ts +19 -15
  159. package/lib/cim/components/Hypershift/HostedClusterWizard/DetailsStep/DetailsStep.tsx +2 -2
  160. package/lib/cim/components/Hypershift/HostedClusterWizard/HostsStep/HostsStep.tsx +2 -13
  161. package/lib/cim/components/Hypershift/HostedClusterWizard/NetworkStep/NetworkStep.tsx +8 -8
  162. package/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx +8 -6
  163. package/lib/cim/components/helpers/versions.ts +51 -34
  164. package/lib/cim/components/modals/CimConfiguration/CimConfigurationModal.tsx +9 -3
  165. package/lib/cim/components/modals/EditProxyModal.tsx +6 -3
  166. package/lib/cim/components/modals/EditPullSecretModal.tsx +1 -1
  167. package/lib/cim/components/modals/EditSSHKeyModal.tsx +8 -6
  168. package/lib/common/components/clusterConfiguration/DiscoveryImageConfigForm.tsx +9 -8
  169. package/lib/common/components/clusterWizard/clusterDetailsValidation.ts +21 -11
  170. package/lib/common/components/hosts/AdditionalNTPSourcesDialog.tsx +3 -6
  171. package/lib/common/components/hosts/EditHostForm.tsx +2 -8
  172. package/lib/common/components/hosts/MassChangeHostnameModal.tsx +4 -6
  173. package/lib/common/components/ui/formik/index.tsx +0 -2
  174. package/lib/common/config/docs_links.ts +1 -1
  175. package/lib/common/index.ts +2 -0
  176. package/lib/common/utils.ts +5 -7
  177. package/lib/common/{components/ui/formik → validationSchemas}/_validationSchemas.test.ts +51 -39
  178. package/lib/common/validationSchemas/addressValidation.tsx +349 -0
  179. package/lib/common/validationSchemas/clusterDetailsValidation.tsx +168 -0
  180. package/lib/common/{components/ui/formik → validationSchemas}/constants.tsx +3 -6
  181. package/lib/common/validationSchemas/hostnameValidation.tsx +46 -0
  182. package/lib/common/validationSchemas/index.tsx +11 -0
  183. package/lib/common/validationSchemas/networkingValidation.tsx +113 -0
  184. package/lib/common/validationSchemas/ntpValidation.tsx +30 -0
  185. package/lib/common/validationSchemas/proxyValidation.tsx +67 -0
  186. package/lib/common/validationSchemas/pullSecretValidation.tsx +24 -0
  187. package/lib/common/validationSchemas/regexes.tsx +22 -0
  188. package/lib/common/validationSchemas/sshValidation.tsx +46 -0
  189. package/lib/common/validationSchemas/utils.tsx +36 -0
  190. package/lib/ocm/components/clusterConfiguration/OcmDiscoveryImageConfigForm.tsx +17 -15
  191. package/lib/ocm/components/clusterConfiguration/manifestsConfiguration/components/CustomManifests.tsx +4 -2
  192. package/lib/ocm/components/clusterConfiguration/manifestsConfiguration/components/customManifestsValidationSchema.tsx +31 -31
  193. package/lib/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfigurationForm.tsx +9 -2
  194. package/lib/ocm/components/clusterConfiguration/networkConfiguration/networkConfigurationValidation.ts +14 -16
  195. package/lib/ocm/components/clusterConfiguration/staticIp/components/FormViewHosts/FormViewHosts.tsx +3 -1
  196. package/lib/ocm/components/clusterConfiguration/staticIp/components/FormViewHosts/formViewHostsValidationSchema.tsx +11 -6
  197. package/lib/ocm/components/clusterConfiguration/staticIp/components/YamlView/YamlView.tsx +5 -1
  198. package/lib/ocm/components/clusterConfiguration/staticIp/components/YamlView/yamlViewValidationSchema.tsx +33 -28
  199. package/lib/ocm/components/clusterWizard/disconnected/OptionalConfigurationsStep.tsx +5 -3
  200. package/lib/ocm/components/hosts/UpdateDay2ApiVipForm.tsx +3 -7
  201. package/package.json +3 -3
  202. package/build/@types/common/components/ui/formik/constants.d.ts.map +0 -1
  203. package/build/@types/common/components/ui/formik/validationSchemas.d.ts +0 -50
  204. package/build/@types/common/components/ui/formik/validationSchemas.d.ts.map +0 -1
  205. package/build/cjs/common/components/ui/formik/constants.js.map +0 -1
  206. package/build/cjs/common/components/ui/formik/validationSchemas.js +0 -553
  207. package/build/cjs/common/components/ui/formik/validationSchemas.js.map +0 -1
  208. package/lib/common/components/ui/formik/validationSchemas.ts +0 -803
@@ -1,803 +0,0 @@
1
- import { overlap } from 'cidr-tools';
2
- import { Address4, Address6 } from 'ip-address';
3
- import isCIDR from 'is-cidr';
4
- import { isInSubnet } from 'is-in-subnet';
5
- import * as Yup from 'yup';
6
- import parseUrl from 'parse-url';
7
-
8
- import { TFunction } from 'i18next';
9
- import {
10
- ClusterNetwork,
11
- MachineNetwork,
12
- ServiceNetwork,
13
- } from '@openshift-assisted/types/assisted-installer-service';
14
- import { NO_SUBNET_SET } from '../../../config/constants';
15
- import { ProxyFieldsType } from '../../../types';
16
- import { HostSubnets, NetworkConfigurationValues } from '../../../types/clusters';
17
- import { getSubnet } from '../../clusterConfiguration/utils';
18
- import {
19
- bmcAddressValidationMessages,
20
- clusterNameValidationMessages,
21
- CLUSTER_NAME_MAX_LENGTH,
22
- FORBIDDEN_HOSTNAMES,
23
- hostnameValidationMessages,
24
- locationValidationMessages,
25
- nameValidationMessages,
26
- } from './constants';
27
- import { allSubnetsIPv4, getAddress, trimCommaSeparatedList, trimSshPublicKey } from './utils';
28
- import { isMajorMinorVersionEqualOrGreater } from '../../../utils';
29
- import { ClusterDetailsValues } from '../../clusterWizard/types';
30
-
31
- const ALPHANUMERIC_REGEX = /^[a-zA-Z0-9]+$/;
32
- const NAME_START_END_REGEX = /^[a-z0-9](.*[a-z0-9])?$/;
33
- const NAME_CHARS_REGEX = /^[a-z0-9-.]*$/;
34
- const CLUSTER_NAME_START_END_REGEX = /^[a-z0-9](.*[a-z0-9])?$/;
35
- const CLUSTER_NAME_VALID_CHARS_REGEX = /^[a-z0-9-]*$/;
36
- const SSH_PUBLIC_KEY_REGEX =
37
- /^(ssh-rsa AAAAB3NzaC1yc2|ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNT|ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzOD|ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1Mj|ssh-ed25519 AAAAC3NzaC1lZDI1NTE5|ssh-dss AAAAB3NzaC1kc3)[0-9A-Za-z+/]+[=]{0,3}( .*)?$/;
38
- const DNS_NAME_REGEX = /^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/;
39
-
40
- const PROXY_DNS_REGEX =
41
- /(^\.?([a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62}){1}(\.[a-zA-Z0-9_]{1}[a-zA-Z0-9_-]{0,62})*$)/;
42
- const IP_V4_ZERO = '0.0.0.0';
43
- const IP_V6_ZERO = '0000:0000:0000:0000:0000:0000:0000:0000';
44
- const MAC_REGEX = /^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$/;
45
- const HOST_NAME_REGEX = /^[^.]{1,63}(?:[.][^.]{1,63})*$/;
46
- const LOCATION_CHARS_REGEX = /^[a-zA-Z0-9-._]*$/;
47
-
48
- export const nameValidationSchema = (
49
- t: TFunction,
50
- usedClusterNames: string[],
51
- baseDnsDomain = '',
52
- validateUniqueName?: boolean,
53
- isOcm = false,
54
- ) => {
55
- const clusterNameValidationMessagesList = clusterNameValidationMessages(t);
56
- return Yup.string()
57
- .required(t('ai:Required field'))
58
- .matches(CLUSTER_NAME_VALID_CHARS_REGEX, {
59
- message: clusterNameValidationMessagesList.INVALID_VALUE,
60
- excludeEmptyString: true,
61
- })
62
- .matches(CLUSTER_NAME_START_END_REGEX, {
63
- message: clusterNameValidationMessagesList.INVALID_START_END,
64
- excludeEmptyString: true,
65
- })
66
- .min(
67
- isOcm ? 1 : 2,
68
- isOcm
69
- ? clusterNameValidationMessagesList.INVALID_LENGTH_OCM
70
- : clusterNameValidationMessagesList.INVALID_LENGTH_ACM,
71
- )
72
- .max(
73
- CLUSTER_NAME_MAX_LENGTH,
74
- isOcm
75
- ? clusterNameValidationMessagesList.INVALID_LENGTH_OCM
76
- : clusterNameValidationMessagesList.INVALID_LENGTH_ACM,
77
- )
78
- .when('useRedHatDnsService', {
79
- is: (useRedHatDnsService: ClusterDetailsValues['useRedHatDnsService']) =>
80
- useRedHatDnsService === true,
81
- then: (schema) =>
82
- schema.test(
83
- 'is-name-unique',
84
- clusterNameValidationMessagesList.NOT_UNIQUE,
85
- (value?: string) => {
86
- const clusterFullName = `${value || ''}.${baseDnsDomain}`;
87
- return !value || !usedClusterNames.includes(clusterFullName);
88
- },
89
- ),
90
- otherwise: (schema) =>
91
- schema.test(
92
- 'is-name-unique',
93
- clusterNameValidationMessagesList.NOT_UNIQUE,
94
- (value?: string) => {
95
- // in CIM cluster name is ClusterDeployment CR name which must be unique
96
- return validateUniqueName ? !value || !usedClusterNames.includes(value) : true;
97
- },
98
- ),
99
- });
100
- };
101
-
102
- export const sshPublicKeyValidationSchema = Yup.string().test(
103
- 'ssh-public-key',
104
- 'SSH public key must consist of "[TYPE] key [[EMAIL]]", supported types are: ssh-rsa, ssh-ed25519, ecdsa-[VARIANT]. A single key can be provided only.',
105
- (value?: string) => {
106
- if (!value) {
107
- return true;
108
- }
109
-
110
- return !!trimSshPublicKey(value).match(SSH_PUBLIC_KEY_REGEX);
111
- },
112
- );
113
-
114
- export const sshPublicKeyListValidationSchema = Yup.string()
115
- .test(
116
- 'ssh-public-keys',
117
- 'SSH public key must consist of "[TYPE] key [[EMAIL]]", supported types are: ssh-rsa, ssh-ed25519, ecdsa-[VARIANT].',
118
- (value?: string) => {
119
- if (!value) {
120
- return true;
121
- }
122
-
123
- return (
124
- trimSshPublicKey(value)
125
- .split('\n')
126
- .find((line: string) => !line.match(SSH_PUBLIC_KEY_REGEX)) === undefined
127
- );
128
- },
129
- )
130
- .test('ssh-public-keys-unique', 'SSH public keys must be unique.', (value?: string) => {
131
- if (!value) {
132
- return true;
133
- }
134
- const keyList = trimSshPublicKey(value).split('\n');
135
- return new Set(keyList).size === keyList.length;
136
- });
137
-
138
- export const pullSecretValidationSchema = Yup.string().test(
139
- 'is-well-formed-json',
140
- "Invalid pull secret format. You must use your Red Hat account's pull secret.",
141
- (value?: string) => {
142
- const isValid = true;
143
- if (!value) return isValid;
144
- try {
145
- const pullSecret = JSON.parse(value) as {
146
- auths: string;
147
- };
148
- return (
149
- pullSecret.constructor.name === 'Object' &&
150
- !!pullSecret?.auths &&
151
- pullSecret.auths.constructor.name === 'Object'
152
- );
153
- } catch {
154
- return !isValid;
155
- }
156
- },
157
- );
158
-
159
- const isValidIpWithoutSuffix = (addr: string) => {
160
- const address = getAddress(addr);
161
- return !!address && address.address === address.addressMinusSuffix;
162
- };
163
-
164
- export const ipValidationSchema = Yup.string().test(
165
- 'ip-validation',
166
- 'Not a valid IP address',
167
- (value?: string) => Address4.isValid(value || '') || Address6.isValid(value || ''),
168
- );
169
-
170
- // Helpers to classify literal IPs more robustly
171
- const isIPv4Address = (ip?: string) => {
172
- if (!ip) return false;
173
- return ip.includes('.') && Address4.isValid(ip);
174
- };
175
-
176
- const isIPv6Address = (ip?: string) => {
177
- if (!ip) return false;
178
- return ip.includes(':') && Address6.isValid(ip);
179
- };
180
-
181
- export const ipNoSuffixValidationSchema = Yup.string().test(
182
- 'ip-validation-no-suffix',
183
- 'Not a valid IP address',
184
- (value?: string) => {
185
- return isValidIpWithoutSuffix(value || '');
186
- },
187
- );
188
-
189
- export const macAddressValidationSchema = Yup.string().matches(MAC_REGEX, {
190
- message: 'Value "${value}" is not valid MAC address.', // eslint-disable-line no-template-curly-in-string
191
- excludeEmptyString: true,
192
- });
193
-
194
- export const vipRangeValidationSchema = (
195
- hostSubnets: HostSubnets,
196
- { machineNetworks }: NetworkConfigurationValues,
197
- allowSuffix: boolean,
198
- ) =>
199
- Yup.string().test('vip-validation', 'IP Address is outside of selected subnet', (value) => {
200
- if (!value) {
201
- return true;
202
- }
203
-
204
- try {
205
- const validator = allowSuffix ? ipValidationSchema : ipNoSuffixValidationSchema;
206
- validator.validateSync(value);
207
- } catch (err) {
208
- return true;
209
- }
210
- // Find host subnets that match the selected machine networks
211
- const cidrs = machineNetworks?.map((network) => network.cidr) ?? [];
212
- const matchingSubnets = hostSubnets.filter((hostSubnet) => cidrs.includes(hostSubnet.subnet));
213
-
214
- for (const hostSubnet of matchingSubnets) {
215
- if (hostSubnet?.subnet) {
216
- // Workaround for bug in CIM backend. hostIDs are empty
217
- if (!hostSubnet.hostIDs.length) {
218
- return true;
219
- } else if (isInSubnet(value, hostSubnet.subnet)) {
220
- return true;
221
- }
222
- }
223
- }
224
- return false;
225
- });
226
-
227
- const vipBroadcastValidationSchema = ({ machineNetworks }: NetworkConfigurationValues) =>
228
- Yup.string().test(
229
- 'vip-no-broadcast',
230
- 'The IP address cannot be a network or broadcast address',
231
- function (value?: string) {
232
- if (!value) {
233
- return true;
234
- }
235
-
236
- const vipAddress = getAddress(value)?.address;
237
- if (!vipAddress) {
238
- return true;
239
- }
240
-
241
- const index = getArrayIndexFromPath(this.path || '');
242
- const machineNetworkCidr = machineNetworks?.[index]?.cidr ?? machineNetworks?.[0]?.cidr ?? '';
243
- if (!machineNetworkCidr) {
244
- return true;
245
- }
246
-
247
- const machineNetwork = getAddress(machineNetworkCidr);
248
- if (!machineNetwork) {
249
- return true;
250
- }
251
-
252
- const machineNetworkBroadcast = machineNetwork.endAddress().address;
253
- const machineNetworkAddress = machineNetwork.startAddress().address;
254
-
255
- return vipAddress !== machineNetworkBroadcast && vipAddress !== machineNetworkAddress;
256
- },
257
- );
258
-
259
- const alwaysRequired = (message?: string) =>
260
- Yup.string().test(
261
- 'always-required',
262
- message || 'The value is required.',
263
- (value?: string): boolean => !!value,
264
- );
265
-
266
- const getArrayIndexFromPath = (path: string): number => {
267
- const match = path.match(/\[(\d+)\][^\[]*$/); // Prefer the last [...] occurrence for nested array paths like "foo[0].bar[1].ip"
268
- return match ? parseInt(match[1], 10) : NaN;
269
- };
270
-
271
- export const hostSubnetValidationSchema = Yup.string().when(['managedNetworkingType'], {
272
- is: (managedNetworkingType: NetworkConfigurationValues['managedNetworkingType']) =>
273
- managedNetworkingType === 'clusterManaged',
274
- then: () => Yup.string().notOneOf([NO_SUBNET_SET], 'Host subnet must be selected.'),
275
- });
276
-
277
- export const vipNoSuffixValidationSchema = (
278
- hostSubnets: HostSubnets,
279
- values: NetworkConfigurationValues,
280
- ) =>
281
- Yup.mixed().when(['vipDhcpAllocation', 'managedNetworkingType'], {
282
- is: (
283
- vipDhcpAllocation: NetworkConfigurationValues['vipDhcpAllocation'],
284
- managedNetworkingType: NetworkConfigurationValues['managedNetworkingType'],
285
- ) => !vipDhcpAllocation && managedNetworkingType !== 'userManaged',
286
- then: () => {
287
- // Per-item schema for VIPs (apiVips[*].ip / ingressVips[*].ip)
288
- // 1) Require value once set
289
- // 2) Validate IP without suffix
290
- // 3) Ensure VIP family matches machineNetworks[idx] family
291
- // 4) Validate range vs selected subnets
292
- // 5) No broadcast/network address
293
- // 6) Uniqueness across API/Ingress
294
- const vipFamilyMatchSchema = Yup.string().test(
295
- 'vip-family-match-machine-network',
296
- 'IP family must match the corresponding machine network family.',
297
- function (value?: string) {
298
- if (!value) {
299
- return true;
300
- }
301
- const index = getArrayIndexFromPath(this.path || '');
302
- if (Number.isNaN(index)) {
303
- return true;
304
- }
305
- const cidr = values.machineNetworks?.[index]?.cidr || '';
306
- const mnIsV4 = isCIDR.v4(cidr);
307
- const mnIsV6 = isCIDR.v6(cidr);
308
- // If machine network at index is not selected/valid, don't block validation here
309
- if (!mnIsV4 && !mnIsV6) {
310
- return true;
311
- }
312
- const ipIsV4 = isIPv4Address(value);
313
- const ipIsV6 = isIPv6Address(value);
314
- if (!ipIsV4 && !ipIsV6) {
315
- return true;
316
- }
317
- return mnIsV4 ? ipIsV4 : ipIsV6;
318
- },
319
- );
320
- // Ensure API and Ingress VIPs at the same index are not the same
321
- const vipUniqueSchema = Yup.string().test('vip-uniqueness', function (value?: string) {
322
- if (!value) {
323
- return true;
324
- }
325
- const index = getArrayIndexFromPath(this.path || '');
326
- if (Number.isNaN(index)) {
327
- return true;
328
- }
329
- const apiVip = values.apiVips?.[index]?.ip;
330
- const ingressVip = values.ingressVips?.[index]?.ip;
331
- if (!apiVip || !ingressVip) {
332
- return true;
333
- }
334
- if (apiVip === ingressVip) {
335
- const label = index === 0 ? 'primary' : 'secondary';
336
- return this.createError({
337
- message: `The ${label} Ingress and API IP addresses cannot be the same.`,
338
- });
339
- }
340
- return true;
341
- });
342
-
343
- return alwaysRequired('Required. Please provide an IP address')
344
- .concat(ipNoSuffixValidationSchema)
345
- .concat(vipFamilyMatchSchema)
346
- .concat(vipRangeValidationSchema(hostSubnets, values, false))
347
- .concat(vipBroadcastValidationSchema(values))
348
- .concat(vipUniqueSchema);
349
- },
350
- });
351
-
352
- export const vipArrayValidationSchema = <T extends Yup.Maybe<Yup.AnyObject>>(
353
- hostSubnets: HostSubnets,
354
- values: NetworkConfigurationValues,
355
- ) =>
356
- values.managedNetworkingType === 'clusterManaged'
357
- ? Yup.array<T>().of(
358
- Yup.object({
359
- clusterId: Yup.string(),
360
- ip: vipNoSuffixValidationSchema(hostSubnets, values),
361
- }),
362
- )
363
- : Yup.array<T>();
364
-
365
- export const ipBlockValidationSchema = (reservedCidrs: string | string[] | undefined) =>
366
- Yup.string()
367
- .required('A value is required.')
368
- .test(
369
- 'valid-ip-address',
370
- 'Invalid IP address block. Expected value is a network expressed in CIDR notation (IP/netmask). For example: 123.123.123.0/24, 2055:d7a::/116',
371
- (value?: string): boolean => !!value && (isCIDR.v4(value) || isCIDR.v6(value)),
372
- )
373
- .test(
374
- 'valid-netmask',
375
- 'IPv4 netmask must be between 1-25 and include at least 128 addresses.\nIPv6 netmask must be between 8-128 and include at least 256 addresses.',
376
- (value?: string) => {
377
- const suffix = parseInt((value || '').split('/')[1]);
378
-
379
- return (
380
- (isCIDR.v4(value || '') && 0 < suffix && suffix < 26) ||
381
- (isCIDR.v6(value || '') && 7 < suffix && suffix < 129)
382
- );
383
- },
384
- )
385
- .test(
386
- 'cidr-is-not-unspecified',
387
- 'The specified CIDR is invalid because its resulting routing prefix matches the unspecified address.',
388
- (cidr: string) => {
389
- const ip = getSubnet(cidr);
390
- if (ip === null) {
391
- return false;
392
- }
393
-
394
- // The first address is used to represent the network
395
- const startAddress = ip.startAddress().address;
396
-
397
- return startAddress !== IP_V4_ZERO && startAddress !== IP_V6_ZERO;
398
- },
399
- )
400
- .test(
401
- 'valid-cidr-base-address',
402
- ({ value }) => `${value as string} is not a valid CIDR`,
403
- (cidr: string) => {
404
- const ip = getSubnet(cidr);
405
- if (ip === null) {
406
- return false;
407
- }
408
-
409
- const networkAddress = ip.startAddress().parsedAddress;
410
- const ipAddress = ip.parsedAddress;
411
- const result = ipAddress.every((part, idx) => part === networkAddress[idx]);
412
-
413
- return result;
414
- },
415
- )
416
- .test('cidrs-can-not-overlap', 'Provided CIDRs can not overlap.', (cidr: string) => {
417
- try {
418
- if (cidr && reservedCidrs && reservedCidrs.length > 0) {
419
- return !overlap(cidr, reservedCidrs);
420
- }
421
- } catch {
422
- return false;
423
- }
424
- // passing by default
425
- return true;
426
- });
427
-
428
- export const dnsNameValidationSchema = Yup.string()
429
- .test(
430
- 'dns-name-label-length',
431
- 'Single label of the DNS name can not be longer than 63 characters.',
432
- (value?: string) => (value || '').split('.').every((label: string) => label.length <= 63),
433
- )
434
- .matches(DNS_NAME_REGEX, {
435
- message: 'Value "${value}" is not valid DNS name. Example: basedomain.example.com', // eslint-disable-line no-template-curly-in-string
436
- excludeEmptyString: true,
437
- });
438
-
439
- export const baseDomainValidationSchema = Yup.string().test(
440
- 'dns-name-label-length',
441
- 'Every single host component in the base domain name cannot contain more than 63 characters and must not contain spaces.',
442
- (value?: string) => {
443
- // Check if the value contains any spaces
444
- if (/\s/.test(value as string)) {
445
- return false; // Value contains spaces, validation fails
446
- }
447
-
448
- // Check the label lengths
449
- const labels = (value || '').split('.');
450
- return labels.every((label: string) => label.length <= 63);
451
- },
452
- );
453
-
454
- export const hostPrefixValidationSchema = (
455
- clusterNetworkCidr: NetworkConfigurationValues['clusterNetworkCidr'],
456
- ) => {
457
- const requiredText = 'The host prefix is required.';
458
- const minMaxText =
459
- 'The host prefix is a number between 1 and 32 for IPv4 and between 8 and 128 for IPv6.';
460
- const netBlock = (clusterNetworkCidr || '').split('/')[1];
461
- if (!netBlock) {
462
- return Yup.number().required(requiredText).min(1, minMaxText).max(32, minMaxText);
463
- }
464
-
465
- let netBlockNumber = parseInt(netBlock);
466
- if (isNaN(netBlockNumber)) {
467
- netBlockNumber = 1;
468
- }
469
-
470
- const errorMsgPrefix =
471
- 'The host prefix is a number between size of the cluster network CIDR range';
472
- const errorMsgIPv4 = `${errorMsgPrefix} (${netBlockNumber}) and 25.`;
473
- const errorMsgIPv6 = `${errorMsgPrefix} (8) and 128.`;
474
-
475
- if (isCIDR.v6(clusterNetworkCidr || '')) {
476
- return Yup.number().required(requiredText).min(8, errorMsgIPv6).max(128, errorMsgIPv6);
477
- }
478
-
479
- if (isCIDR.v4(clusterNetworkCidr || '')) {
480
- return Yup.number()
481
- .required(requiredText)
482
- .min(netBlockNumber, errorMsgIPv4)
483
- .max(25, errorMsgIPv4);
484
- }
485
-
486
- return Yup.number().required(requiredText);
487
- };
488
-
489
- export const richNameValidationSchema = (t: TFunction, usedNames: string[], origName?: string) => {
490
- const nameValidationMessagesList = nameValidationMessages(t);
491
- return Yup.string()
492
- .min(1, nameValidationMessagesList.INVALID_LENGTH)
493
- .max(253, nameValidationMessagesList.INVALID_LENGTH)
494
- .test(
495
- nameValidationMessagesList.INVALID_START_END,
496
- nameValidationMessagesList.INVALID_START_END,
497
- (value?: string) => {
498
- const trimmed = value?.trim();
499
- if (!trimmed) {
500
- return true;
501
- }
502
- return (
503
- !!trimmed[0].match(NAME_START_END_REGEX) &&
504
- (trimmed[trimmed.length - 1]
505
- ? !!trimmed[trimmed.length - 1].match(NAME_START_END_REGEX)
506
- : true)
507
- );
508
- },
509
- )
510
- .matches(HOST_NAME_REGEX, nameValidationMessagesList.INVALID_FORMAT)
511
- .matches(NAME_CHARS_REGEX, {
512
- message: nameValidationMessagesList.INVALID_VALUE,
513
- excludeEmptyString: true,
514
- })
515
- .test(nameValidationMessagesList.NOT_UNIQUE, nameValidationMessagesList.NOT_UNIQUE, (value) => {
516
- if (!value || value === origName) {
517
- return true;
518
- }
519
- return !usedNames.find((n) => n === value);
520
- })
521
- .notOneOf(FORBIDDEN_HOSTNAMES, hostnameValidationMessages(t).LOCALHOST_ERR);
522
- };
523
-
524
- export const richHostnameValidationSchema = (
525
- t: TFunction,
526
- usedNames: string[],
527
- origName?: string,
528
- ) => {
529
- const hostnameValidationMessagesList = hostnameValidationMessages(t);
530
- return Yup.string()
531
- .min(1, hostnameValidationMessagesList.INVALID_LENGTH)
532
- .max(63, hostnameValidationMessagesList.INVALID_LENGTH)
533
- .test(
534
- hostnameValidationMessagesList.INVALID_START_END,
535
- hostnameValidationMessagesList.INVALID_START_END,
536
- (value?: string) => {
537
- const trimmed = value?.trim();
538
- if (!trimmed) {
539
- return true;
540
- }
541
- return (
542
- !!trimmed[0].match(NAME_START_END_REGEX) &&
543
- (trimmed[trimmed.length - 1]
544
- ? !!trimmed[trimmed.length - 1].match(NAME_START_END_REGEX)
545
- : true)
546
- );
547
- },
548
- )
549
- .matches(NAME_CHARS_REGEX, {
550
- message: hostnameValidationMessagesList.INVALID_VALUE,
551
- excludeEmptyString: true,
552
- })
553
- .test(
554
- hostnameValidationMessagesList.NOT_UNIQUE,
555
- hostnameValidationMessagesList.NOT_UNIQUE,
556
- (value) => {
557
- if (!value || value === origName) {
558
- return true;
559
- }
560
- return !usedNames.find((n) => n === value);
561
- },
562
- )
563
- .notOneOf(FORBIDDEN_HOSTNAMES, hostnameValidationMessagesList.LOCALHOST_ERR);
564
- };
565
-
566
- const httpProxyValidationMessage = 'Provide a valid HTTP URL.';
567
- export const httpProxyValidationSchema = ({
568
- values,
569
- pairValueName,
570
- allowEmpty,
571
- }: {
572
- values: ProxyFieldsType;
573
- pairValueName: 'httpProxy' | 'httpsProxy';
574
- allowEmpty?: boolean;
575
- }) => {
576
- const validation = Yup.string().test(
577
- 'http-proxy-validation',
578
- httpProxyValidationMessage,
579
- (value?: string) => {
580
- if (!value) {
581
- return true;
582
- }
583
-
584
- if (!value.startsWith('http://')) {
585
- return false;
586
- }
587
-
588
- try {
589
- new URL(value);
590
- } catch {
591
- return false;
592
- }
593
- return true;
594
- },
595
- );
596
-
597
- if (allowEmpty) {
598
- return validation;
599
- }
600
-
601
- return validation.test(
602
- 'http-proxy-no-empty-validation',
603
- 'At least one of the HTTP or HTTPS proxy URLs is required.',
604
- (value) => !values.enableProxy || !!value || !!values[pairValueName],
605
- );
606
- };
607
-
608
- const isIPorDN = (value?: string, dnsRegex = DNS_NAME_REGEX) => {
609
- if ((value as string).match(dnsRegex)) {
610
- return true;
611
- }
612
- try {
613
- ipValidationSchema.validateSync(value);
614
- return true;
615
- } catch (err) {
616
- return false;
617
- }
618
- };
619
-
620
- export const noProxyValidationSchema = Yup.string().test(
621
- 'no-proxy-validation',
622
- 'Provide a comma separated list of valid DNS names or IP addresses.',
623
- (value?: string) => {
624
- if (!value || value === '*') {
625
- return true;
626
- }
627
-
628
- // https://docs.openshift.com/container-platform/4.5/installing/installing_bare_metal/installing-restricted-networks-bare-metal.html#installation-configure-proxy_installing-restricted-networks-bare-metal
629
- // A comma-separated list of destination domain names, domains, IP addresses, or other network CIDRs to exclude proxying.
630
- // Preface a domain with . to match subdomains only. For example, .y.com matches x.y.com, but not y.com.
631
- // Use * to bypass proxy for all destinations.
632
- const noProxyList = trimCommaSeparatedList(value).split(',');
633
- return noProxyList.every((p) => isIPorDN(p, PROXY_DNS_REGEX));
634
- },
635
- );
636
-
637
- export const ntpSourceValidationSchema = Yup.string()
638
- .test(
639
- 'ntp-source-validation',
640
- 'Provide a comma separated list of valid DNS names or IP addresses.',
641
- (value?: string) => {
642
- if (!value || value === '') {
643
- return true;
644
- }
645
- return trimCommaSeparatedList(value)
646
- .split(',')
647
- .every((v) => isIPorDN(v));
648
- },
649
- )
650
- .test(
651
- 'ntp-source-validation-unique',
652
- 'DNS names and IP addresses must be unique.',
653
- (value?: string) => {
654
- if (!value || value === '') {
655
- return true;
656
- }
657
- const arr = trimCommaSeparatedList(value).split(',');
658
- return arr.length === new Set(arr).size;
659
- },
660
- );
661
-
662
- export const day2ApiVipValidationSchema = Yup.string().test(
663
- 'day2-api-vip',
664
- 'Provide a valid DNS name or IP Address',
665
- (value?: string) => {
666
- if (!value) {
667
- return true;
668
- }
669
- return isIPorDN(value);
670
- },
671
- );
672
-
673
- export const bmcAddressValidationSchema = (t: TFunction) => {
674
- const bmcAddressValidationMessagesList = bmcAddressValidationMessages(t);
675
-
676
- return Yup.string()
677
- .required()
678
- .test('valid-bmc-address', bmcAddressValidationMessagesList.INVALID_VALUE, (val) => {
679
- try {
680
- const url = parseUrl(val);
681
- return ['redfish-virtualmedia', 'idrac-virtualmedia'].includes(url.protocol as string);
682
- } catch (error) {
683
- return false;
684
- }
685
- });
686
- };
687
- export const locationValidationSchema = (t: TFunction) => {
688
- const locationValidationMessagesList = locationValidationMessages(t);
689
- return Yup.string()
690
- .min(1, locationValidationMessagesList.INVALID_LENGTH)
691
- .max(63, locationValidationMessagesList.INVALID_LENGTH)
692
- .test(
693
- locationValidationMessagesList.INVALID_START_END,
694
- locationValidationMessagesList.INVALID_START_END,
695
- (value?: string) => {
696
- const trimmed = value?.trim();
697
- if (!trimmed) {
698
- return true;
699
- }
700
- return (
701
- !!trimmed[0].match(ALPHANUMERIC_REGEX) &&
702
- (trimmed[trimmed.length - 1]
703
- ? !!trimmed[trimmed.length - 1].match(ALPHANUMERIC_REGEX)
704
- : true)
705
- );
706
- },
707
- )
708
- .matches(LOCATION_CHARS_REGEX, {
709
- message: locationValidationMessagesList.INVALID_VALUE,
710
- excludeEmptyString: true,
711
- });
712
- };
713
-
714
- export const machineNetworksValidationSchema = Yup.array().of(
715
- Yup.object({ cidr: hostSubnetValidationSchema, clusterId: Yup.string() }),
716
- );
717
-
718
- export const clusterNetworksValidationSchema = Yup.array().of(
719
- Yup.lazy((values: ClusterNetwork) =>
720
- Yup.object({
721
- cidr: ipBlockValidationSchema(
722
- undefined /* So far used in OCM only and so validated by backend */,
723
- ),
724
- hostPrefix: hostPrefixValidationSchema(values.cidr),
725
- clusterId: Yup.string(),
726
- }),
727
- ),
728
- );
729
-
730
- export const serviceNetworkValidationSchema = Yup.array().of(
731
- Yup.object({
732
- cidr: ipBlockValidationSchema(
733
- undefined /* So far used in OCM only and so validated by backend */,
734
- ),
735
- clusterId: Yup.string(),
736
- }),
737
- );
738
-
739
- export const dualStackValidationSchema = (field: string, openshiftVersion?: string) =>
740
- Yup.array()
741
- .max(2, `Maximum number of ${field} subnets in dual stack is 2.`)
742
- .test(
743
- 'dual-stack-ipv4',
744
- openshiftVersion && isMajorMinorVersionEqualOrGreater(openshiftVersion, '4.12')
745
- ? 'First network has to be a valid IPv4 or IPv6 subnet.'
746
- : 'First network has to be IPv4 subnet.',
747
- (values?: { cidr: MachineNetwork['cidr'] }[]): boolean => {
748
- // For OCP versions > 4.11, allow IPv6 as primary network
749
- if (openshiftVersion && isMajorMinorVersionEqualOrGreater(openshiftVersion, '4.12')) {
750
- return !!values?.[0].cidr && (isCIDR.v4(values[0].cidr) || isCIDR.v6(values[0].cidr));
751
- }
752
- // For older versions, require IPv4 as primary network
753
- return !!values?.[0].cidr && isCIDR.v4(values[0].cidr);
754
- },
755
- )
756
- .test(
757
- 'dual-stack-unique-cidrs',
758
- `Provided ${field} subnets must be unique.`,
759
- (values?: { cidr?: MachineNetwork['cidr'] }[]) => {
760
- if (!values || values.length < 2) {
761
- return true;
762
- }
763
- const first = values[0]?.cidr || '';
764
- const second = values[1]?.cidr || '';
765
- if (!first || !second) {
766
- return true;
767
- }
768
- const firstIsCidr = isCIDR.v4(first) || isCIDR.v6(first);
769
- const secondIsCidr = isCIDR.v4(second) || isCIDR.v6(second);
770
- if (!firstIsCidr || !secondIsCidr) {
771
- return true;
772
- }
773
- return first !== second;
774
- },
775
- )
776
- .test(
777
- 'dual-stack-opposite-families',
778
- `When two ${field} are provided, one must be IPv4 and the other IPv6.`,
779
- (values?: { cidr?: MachineNetwork['cidr'] }[]) => {
780
- if (!values || values.length < 2) {
781
- return true;
782
- }
783
- const a = values[0]?.cidr || '';
784
- const b = values[1]?.cidr || '';
785
- if (!a || !b) {
786
- return true;
787
- }
788
- const a4 = isCIDR.v4(a);
789
- const a6 = isCIDR.v6(a);
790
- const b4 = isCIDR.v4(b);
791
- const b6 = isCIDR.v6(b);
792
- if (!((a4 || a6) && (b4 || b6))) {
793
- return true;
794
- }
795
- return (a4 && b6) || (a6 && b4);
796
- },
797
- );
798
-
799
- export const IPv4ValidationSchema = Yup.array().test(
800
- 'single-stack',
801
- `All network subnets must be IPv4.`,
802
- (values?: (MachineNetwork | ClusterNetwork | ServiceNetwork)[]) => allSubnetsIPv4(values),
803
- );