@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.
- package/build/@types/cim/components/ClusterDeployment/clusterDetails/ClusterDeploymentDetailsForm.d.ts.map +1 -1
- package/build/@types/cim/components/ClusterDeployment/clusterDetails/ClusterDetailsFormFields.d.ts +0 -1
- package/build/@types/cim/components/ClusterDeployment/clusterDetails/ClusterDetailsFormFields.d.ts.map +1 -1
- package/build/@types/cim/components/ClusterDeployment/hostSelection/ClusterDeploymentHostSelectionStep.d.ts.map +1 -1
- package/build/@types/cim/components/ClusterDeployment/use-networking-formik.d.ts.map +1 -1
- package/build/@types/cim/components/Hypershift/HostedClusterWizard/HostsStep/HostsStep.d.ts.map +1 -1
- package/build/@types/cim/components/InfraEnv/InfraEnvFormPage.d.ts.map +1 -1
- package/build/@types/cim/components/helpers/versions.d.ts +1 -1
- package/build/@types/cim/components/helpers/versions.d.ts.map +1 -1
- package/build/@types/cim/components/modals/CimConfiguration/CimConfigurationModal.d.ts.map +1 -1
- package/build/@types/cim/components/modals/EditProxyModal.d.ts.map +1 -1
- package/build/@types/cim/components/modals/EditSSHKeyModal.d.ts.map +1 -1
- package/build/@types/common/components/clusterConfiguration/DiscoveryImageConfigForm.d.ts.map +1 -1
- package/build/@types/common/components/clusterWizard/clusterDetailsValidation.d.ts.map +1 -1
- package/build/@types/common/components/hosts/AdditionalNTPSourcesDialog.d.ts.map +1 -1
- package/build/@types/common/components/hosts/EditHostForm.d.ts.map +1 -1
- package/build/@types/common/components/hosts/MassChangeHostnameModal.d.ts.map +1 -1
- package/build/@types/common/components/ui/formik/index.d.ts +0 -2
- package/build/@types/common/components/ui/formik/index.d.ts.map +1 -1
- package/build/@types/common/index.d.ts +1 -0
- package/build/@types/common/index.d.ts.map +1 -1
- package/build/@types/common/utils.d.ts +2 -2
- package/build/@types/common/utils.d.ts.map +1 -1
- package/build/@types/common/validationSchemas/addressValidation.d.ts +18 -0
- package/build/@types/common/validationSchemas/addressValidation.d.ts.map +1 -0
- package/build/@types/common/validationSchemas/clusterDetailsValidation.d.ts +8 -0
- package/build/@types/common/validationSchemas/clusterDetailsValidation.d.ts.map +1 -0
- package/build/@types/common/{components/ui/formik → validationSchemas}/constants.d.ts +1 -3
- package/build/@types/common/validationSchemas/constants.d.ts.map +1 -0
- package/build/@types/common/validationSchemas/hostnameValidation.d.ts +4 -0
- package/build/@types/common/validationSchemas/hostnameValidation.d.ts.map +1 -0
- package/build/@types/common/validationSchemas/index.d.ts +11 -0
- package/build/@types/common/validationSchemas/index.d.ts.map +1 -0
- package/build/@types/common/validationSchemas/networkingValidation.d.ts +18 -0
- package/build/@types/common/validationSchemas/networkingValidation.d.ts.map +1 -0
- package/build/@types/common/validationSchemas/ntpValidation.d.ts +4 -0
- package/build/@types/common/validationSchemas/ntpValidation.d.ts.map +1 -0
- package/build/@types/common/validationSchemas/proxyValidation.d.ts +11 -0
- package/build/@types/common/validationSchemas/proxyValidation.d.ts.map +1 -0
- package/build/@types/common/validationSchemas/pullSecretValidation.d.ts +4 -0
- package/build/@types/common/validationSchemas/pullSecretValidation.d.ts.map +1 -0
- package/build/@types/common/validationSchemas/regexes.d.ts +14 -0
- package/build/@types/common/validationSchemas/regexes.d.ts.map +1 -0
- package/build/@types/common/validationSchemas/sshValidation.d.ts +5 -0
- package/build/@types/common/validationSchemas/sshValidation.d.ts.map +1 -0
- package/build/@types/common/validationSchemas/utils.d.ts +7 -0
- package/build/@types/common/validationSchemas/utils.d.ts.map +1 -0
- package/build/@types/ocm/components/clusterConfiguration/OcmDiscoveryImageConfigForm.d.ts.map +1 -1
- package/build/@types/ocm/components/clusterConfiguration/manifestsConfiguration/components/CustomManifests.d.ts.map +1 -1
- package/build/@types/ocm/components/clusterConfiguration/manifestsConfiguration/components/customManifestsValidationSchema.d.ts +2 -1
- package/build/@types/ocm/components/clusterConfiguration/manifestsConfiguration/components/customManifestsValidationSchema.d.ts.map +1 -1
- package/build/@types/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfigurationForm.d.ts.map +1 -1
- package/build/@types/ocm/components/clusterConfiguration/networkConfiguration/networkConfigurationValidation.d.ts +2 -1
- package/build/@types/ocm/components/clusterConfiguration/networkConfiguration/networkConfigurationValidation.d.ts.map +1 -1
- package/build/@types/ocm/components/clusterConfiguration/staticIp/components/FormViewHosts/FormViewHosts.d.ts.map +1 -1
- package/build/@types/ocm/components/clusterConfiguration/staticIp/components/FormViewHosts/formViewHostsValidationSchema.d.ts +2 -1
- package/build/@types/ocm/components/clusterConfiguration/staticIp/components/FormViewHosts/formViewHostsValidationSchema.d.ts.map +1 -1
- package/build/@types/ocm/components/clusterConfiguration/staticIp/components/YamlView/YamlView.d.ts.map +1 -1
- package/build/@types/ocm/components/clusterConfiguration/staticIp/components/YamlView/yamlViewValidationSchema.d.ts +2 -1
- package/build/@types/ocm/components/clusterConfiguration/staticIp/components/YamlView/yamlViewValidationSchema.d.ts.map +1 -1
- package/build/@types/ocm/components/clusterWizard/disconnected/OptionalConfigurationsStep.d.ts.map +1 -1
- package/build/@types/ocm/components/hosts/UpdateDay2ApiVipForm.d.ts.map +1 -1
- package/build/cjs/cim/components/Agent/BMCForm.js +3 -3
- package/build/cjs/cim/components/Agent/BMCForm.js.map +1 -1
- package/build/cjs/cim/components/ClusterDeployment/clusterDetails/ClusterDeploymentDetailsForm.js +9 -15
- package/build/cjs/cim/components/ClusterDeployment/clusterDetails/ClusterDeploymentDetailsForm.js.map +1 -1
- package/build/cjs/cim/components/ClusterDeployment/clusterDetails/ClusterDetailsFormFields.js +8 -6
- package/build/cjs/cim/components/ClusterDeployment/clusterDetails/ClusterDetailsFormFields.js.map +1 -1
- package/build/cjs/cim/components/ClusterDeployment/hostSelection/ClusterDeploymentHostSelectionStep.js +1 -3
- package/build/cjs/cim/components/ClusterDeployment/hostSelection/ClusterDeploymentHostSelectionStep.js.map +1 -1
- package/build/cjs/cim/components/ClusterDeployment/use-networking-formik.js +16 -15
- package/build/cjs/cim/components/ClusterDeployment/use-networking-formik.js.map +1 -1
- package/build/cjs/cim/components/Hypershift/HostedClusterWizard/DetailsStep/DetailsStep.js +2 -2
- package/build/cjs/cim/components/Hypershift/HostedClusterWizard/DetailsStep/DetailsStep.js.map +1 -1
- package/build/cjs/cim/components/Hypershift/HostedClusterWizard/HostsStep/HostsStep.js +2 -11
- package/build/cjs/cim/components/Hypershift/HostedClusterWizard/HostsStep/HostsStep.js.map +1 -1
- package/build/cjs/cim/components/Hypershift/HostedClusterWizard/NetworkStep/NetworkStep.js +8 -8
- package/build/cjs/cim/components/Hypershift/HostedClusterWizard/NetworkStep/NetworkStep.js.map +1 -1
- package/build/cjs/cim/components/InfraEnv/InfraEnvFormPage.js +8 -6
- package/build/cjs/cim/components/InfraEnv/InfraEnvFormPage.js.map +1 -1
- package/build/cjs/cim/components/helpers/versions.js +42 -27
- package/build/cjs/cim/components/helpers/versions.js.map +1 -1
- package/build/cjs/cim/components/modals/CimConfiguration/CimConfigurationModal.js +9 -3
- package/build/cjs/cim/components/modals/CimConfiguration/CimConfigurationModal.js.map +1 -1
- package/build/cjs/cim/components/modals/EditProxyModal.js +5 -3
- package/build/cjs/cim/components/modals/EditProxyModal.js.map +1 -1
- package/build/cjs/cim/components/modals/EditPullSecretModal.js +1 -1
- package/build/cjs/cim/components/modals/EditPullSecretModal.js.map +1 -1
- package/build/cjs/cim/components/modals/EditSSHKeyModal.js +3 -3
- package/build/cjs/cim/components/modals/EditSSHKeyModal.js.map +1 -1
- package/build/cjs/common/components/clusterConfiguration/DiscoveryImageConfigForm.js +7 -6
- package/build/cjs/common/components/clusterConfiguration/DiscoveryImageConfigForm.js.map +1 -1
- package/build/cjs/common/components/clusterWizard/clusterDetailsValidation.js +8 -8
- package/build/cjs/common/components/clusterWizard/clusterDetailsValidation.js.map +1 -1
- package/build/cjs/common/components/hosts/AdditionalNTPSourcesDialog.js +2 -1
- package/build/cjs/common/components/hosts/AdditionalNTPSourcesDialog.js.map +1 -1
- package/build/cjs/common/components/hosts/EditHostForm.js +3 -2
- package/build/cjs/common/components/hosts/EditHostForm.js.map +1 -1
- package/build/cjs/common/components/hosts/MassChangeHostnameModal.js +6 -5
- package/build/cjs/common/components/hosts/MassChangeHostnameModal.js.map +1 -1
- package/build/cjs/common/components/ui/formik/index.js +0 -2
- package/build/cjs/common/components/ui/formik/index.js.map +1 -1
- package/build/cjs/common/config/docs_links.js +1 -1
- package/build/cjs/common/index.js +1 -0
- package/build/cjs/common/index.js.map +1 -1
- package/build/cjs/common/utils.js +5 -3
- package/build/cjs/common/utils.js.map +1 -1
- package/build/cjs/common/validationSchemas/addressValidation.js +246 -0
- package/build/cjs/common/validationSchemas/addressValidation.js.map +1 -0
- package/build/cjs/common/validationSchemas/clusterDetailsValidation.js +104 -0
- package/build/cjs/common/validationSchemas/clusterDetailsValidation.js.map +1 -0
- package/build/cjs/common/{components/ui/formik → validationSchemas}/constants.js +3 -5
- package/build/cjs/common/validationSchemas/constants.js.map +1 -0
- package/build/cjs/common/validationSchemas/hostnameValidation.js +36 -0
- package/build/cjs/common/validationSchemas/hostnameValidation.js.map +1 -0
- package/build/cjs/common/validationSchemas/index.js +17 -0
- package/build/cjs/common/validationSchemas/index.js.map +1 -0
- package/build/cjs/common/validationSchemas/networkingValidation.js +74 -0
- package/build/cjs/common/validationSchemas/networkingValidation.js.map +1 -0
- package/build/cjs/common/validationSchemas/ntpValidation.js +25 -0
- package/build/cjs/common/validationSchemas/ntpValidation.js.map +1 -0
- package/build/cjs/common/validationSchemas/proxyValidation.js +43 -0
- package/build/cjs/common/validationSchemas/proxyValidation.js.map +1 -0
- package/build/cjs/common/validationSchemas/pullSecretValidation.js +21 -0
- package/build/cjs/common/validationSchemas/pullSecretValidation.js.map +1 -0
- package/build/cjs/common/validationSchemas/regexes.js +17 -0
- package/build/cjs/common/validationSchemas/regexes.js.map +1 -0
- package/build/cjs/common/validationSchemas/sshValidation.js +32 -0
- package/build/cjs/common/validationSchemas/sshValidation.js.map +1 -0
- package/build/cjs/common/validationSchemas/utils.js +40 -0
- package/build/cjs/common/validationSchemas/utils.js.map +1 -0
- package/build/cjs/ocm/components/clusterConfiguration/OcmDiscoveryImageConfigForm.js +7 -6
- package/build/cjs/ocm/components/clusterConfiguration/OcmDiscoveryImageConfigForm.js.map +1 -1
- package/build/cjs/ocm/components/clusterConfiguration/manifestsConfiguration/components/CustomManifests.js +4 -2
- package/build/cjs/ocm/components/clusterConfiguration/manifestsConfiguration/components/CustomManifests.js.map +1 -1
- package/build/cjs/ocm/components/clusterConfiguration/manifestsConfiguration/components/customManifestsValidationSchema.js +7 -6
- package/build/cjs/ocm/components/clusterConfiguration/manifestsConfiguration/components/customManifestsValidationSchema.js.map +1 -1
- package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfigurationForm.js +2 -1
- package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfigurationForm.js.map +1 -1
- package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/networkConfigurationValidation.js +11 -11
- package/build/cjs/ocm/components/clusterConfiguration/networkConfiguration/networkConfigurationValidation.js.map +1 -1
- package/build/cjs/ocm/components/clusterConfiguration/staticIp/components/FormViewHosts/FormViewHosts.js +3 -1
- package/build/cjs/ocm/components/clusterConfiguration/staticIp/components/FormViewHosts/FormViewHosts.js.map +1 -1
- package/build/cjs/ocm/components/clusterConfiguration/staticIp/components/FormViewHosts/formViewHostsValidationSchema.js +6 -6
- package/build/cjs/ocm/components/clusterConfiguration/staticIp/components/FormViewHosts/formViewHostsValidationSchema.js.map +1 -1
- package/build/cjs/ocm/components/clusterConfiguration/staticIp/components/YamlView/YamlView.js +3 -1
- package/build/cjs/ocm/components/clusterConfiguration/staticIp/components/YamlView/YamlView.js.map +1 -1
- package/build/cjs/ocm/components/clusterConfiguration/staticIp/components/YamlView/yamlViewValidationSchema.js +12 -12
- package/build/cjs/ocm/components/clusterConfiguration/staticIp/components/YamlView/yamlViewValidationSchema.js.map +1 -1
- package/build/cjs/ocm/components/clusterWizard/disconnected/OptionalConfigurationsStep.js +4 -3
- package/build/cjs/ocm/components/clusterWizard/disconnected/OptionalConfigurationsStep.js.map +1 -1
- package/build/cjs/ocm/components/hosts/UpdateDay2ApiVipForm.js +2 -1
- package/build/cjs/ocm/components/hosts/UpdateDay2ApiVipForm.js.map +1 -1
- package/lib/cim/components/Agent/BMCForm.tsx +3 -3
- package/lib/cim/components/ClusterDeployment/clusterDetails/ClusterDeploymentDetailsForm.tsx +8 -18
- package/lib/cim/components/ClusterDeployment/clusterDetails/ClusterDetailsFormFields.tsx +7 -10
- package/lib/cim/components/ClusterDeployment/hostSelection/ClusterDeploymentHostSelectionStep.tsx +1 -3
- package/lib/cim/components/ClusterDeployment/use-networking-formik.ts +19 -15
- package/lib/cim/components/Hypershift/HostedClusterWizard/DetailsStep/DetailsStep.tsx +2 -2
- package/lib/cim/components/Hypershift/HostedClusterWizard/HostsStep/HostsStep.tsx +2 -13
- package/lib/cim/components/Hypershift/HostedClusterWizard/NetworkStep/NetworkStep.tsx +8 -8
- package/lib/cim/components/InfraEnv/InfraEnvFormPage.tsx +8 -6
- package/lib/cim/components/helpers/versions.ts +51 -34
- package/lib/cim/components/modals/CimConfiguration/CimConfigurationModal.tsx +9 -3
- package/lib/cim/components/modals/EditProxyModal.tsx +6 -3
- package/lib/cim/components/modals/EditPullSecretModal.tsx +1 -1
- package/lib/cim/components/modals/EditSSHKeyModal.tsx +8 -6
- package/lib/common/components/clusterConfiguration/DiscoveryImageConfigForm.tsx +9 -8
- package/lib/common/components/clusterWizard/clusterDetailsValidation.ts +21 -11
- package/lib/common/components/hosts/AdditionalNTPSourcesDialog.tsx +3 -6
- package/lib/common/components/hosts/EditHostForm.tsx +2 -8
- package/lib/common/components/hosts/MassChangeHostnameModal.tsx +4 -6
- package/lib/common/components/ui/formik/index.tsx +0 -2
- package/lib/common/config/docs_links.ts +1 -1
- package/lib/common/index.ts +2 -0
- package/lib/common/utils.ts +5 -7
- package/lib/common/{components/ui/formik → validationSchemas}/_validationSchemas.test.ts +51 -39
- package/lib/common/validationSchemas/addressValidation.tsx +349 -0
- package/lib/common/validationSchemas/clusterDetailsValidation.tsx +168 -0
- package/lib/common/{components/ui/formik → validationSchemas}/constants.tsx +3 -6
- package/lib/common/validationSchemas/hostnameValidation.tsx +46 -0
- package/lib/common/validationSchemas/index.tsx +11 -0
- package/lib/common/validationSchemas/networkingValidation.tsx +113 -0
- package/lib/common/validationSchemas/ntpValidation.tsx +30 -0
- package/lib/common/validationSchemas/proxyValidation.tsx +67 -0
- package/lib/common/validationSchemas/pullSecretValidation.tsx +24 -0
- package/lib/common/validationSchemas/regexes.tsx +22 -0
- package/lib/common/validationSchemas/sshValidation.tsx +46 -0
- package/lib/common/validationSchemas/utils.tsx +36 -0
- package/lib/ocm/components/clusterConfiguration/OcmDiscoveryImageConfigForm.tsx +17 -15
- package/lib/ocm/components/clusterConfiguration/manifestsConfiguration/components/CustomManifests.tsx +4 -2
- package/lib/ocm/components/clusterConfiguration/manifestsConfiguration/components/customManifestsValidationSchema.tsx +31 -31
- package/lib/ocm/components/clusterConfiguration/networkConfiguration/NetworkConfigurationForm.tsx +9 -2
- package/lib/ocm/components/clusterConfiguration/networkConfiguration/networkConfigurationValidation.ts +14 -16
- package/lib/ocm/components/clusterConfiguration/staticIp/components/FormViewHosts/FormViewHosts.tsx +3 -1
- package/lib/ocm/components/clusterConfiguration/staticIp/components/FormViewHosts/formViewHostsValidationSchema.tsx +11 -6
- package/lib/ocm/components/clusterConfiguration/staticIp/components/YamlView/YamlView.tsx +5 -1
- package/lib/ocm/components/clusterConfiguration/staticIp/components/YamlView/yamlViewValidationSchema.tsx +33 -28
- package/lib/ocm/components/clusterWizard/disconnected/OptionalConfigurationsStep.tsx +5 -3
- package/lib/ocm/components/hosts/UpdateDay2ApiVipForm.tsx +3 -7
- package/package.json +3 -3
- package/build/@types/common/components/ui/formik/constants.d.ts.map +0 -1
- package/build/@types/common/components/ui/formik/validationSchemas.d.ts +0 -50
- package/build/@types/common/components/ui/formik/validationSchemas.d.ts.map +0 -1
- package/build/cjs/common/components/ui/formik/constants.js.map +0 -1
- package/build/cjs/common/components/ui/formik/validationSchemas.js +0 -553
- package/build/cjs/common/components/ui/formik/validationSchemas.js.map +0 -1
- package/lib/common/components/ui/formik/validationSchemas.ts +0 -803
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
import * as Yup from 'yup';
|
|
2
|
+
import { Address4, Address6 } from 'ip-address';
|
|
3
|
+
import isCIDR from 'is-cidr';
|
|
4
|
+
import { isInSubnet } from 'is-in-subnet';
|
|
5
|
+
|
|
6
|
+
import { getAddress } from '../components/ui/formik/utils';
|
|
7
|
+
import { getSubnet } from '../components/clusterConfiguration/utils';
|
|
8
|
+
import { HostSubnets, NetworkConfigurationValues } from '../types';
|
|
9
|
+
import { IP_V4_ZERO, IP_V6_ZERO, MAC_REGEX } from './regexes';
|
|
10
|
+
import {
|
|
11
|
+
alwaysRequired,
|
|
12
|
+
getArrayIndexFromPath,
|
|
13
|
+
isIPorDN,
|
|
14
|
+
isIPv4Address,
|
|
15
|
+
isIPv6Address,
|
|
16
|
+
} from './utils';
|
|
17
|
+
import { NO_SUBNET_SET } from '../config';
|
|
18
|
+
import { overlap } from 'cidr-tools';
|
|
19
|
+
import parseUrl from 'parse-url';
|
|
20
|
+
import { TFunction } from 'i18next';
|
|
21
|
+
|
|
22
|
+
export const ipValidationSchema = (t: TFunction) =>
|
|
23
|
+
Yup.string().test(
|
|
24
|
+
'ip-validation',
|
|
25
|
+
t('ai:Not a valid IP address'),
|
|
26
|
+
(value?: string) => Address4.isValid(value || '') || Address6.isValid(value || ''),
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
export const ipNoSuffixValidationSchema = (t: TFunction) =>
|
|
30
|
+
Yup.string().test('ip-validation-no-suffix', t('ai:Not a valid IP address'), (value?: string) => {
|
|
31
|
+
const address = getAddress(value || '');
|
|
32
|
+
return !!address && address.address === address.addressMinusSuffix;
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
export const macAddressValidationSchema = (t: TFunction) =>
|
|
36
|
+
Yup.string().matches(MAC_REGEX, {
|
|
37
|
+
message: (value) => t('ai:Value "{{value}}" is not valid MAC address.', { value }),
|
|
38
|
+
excludeEmptyString: true,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
export const vipRangeValidationSchema = (
|
|
42
|
+
hostSubnets: HostSubnets,
|
|
43
|
+
{ machineNetworks }: NetworkConfigurationValues,
|
|
44
|
+
allowSuffix: boolean,
|
|
45
|
+
t: TFunction,
|
|
46
|
+
) =>
|
|
47
|
+
Yup.string().test('vip-validation', t('ai:IP Address is outside of selected subnet'), (value) => {
|
|
48
|
+
if (!value) {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
const validator = allowSuffix ? ipValidationSchema : ipNoSuffixValidationSchema;
|
|
54
|
+
validator(t).validateSync(value);
|
|
55
|
+
} catch (err) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
// Find host subnets that match the selected machine networks
|
|
59
|
+
const cidrs = machineNetworks?.map((network) => network.cidr) ?? [];
|
|
60
|
+
const matchingSubnets = hostSubnets.filter((hostSubnet) => cidrs.includes(hostSubnet.subnet));
|
|
61
|
+
|
|
62
|
+
for (const hostSubnet of matchingSubnets) {
|
|
63
|
+
if (hostSubnet?.subnet) {
|
|
64
|
+
// Workaround for bug in CIM backend. hostIDs are empty
|
|
65
|
+
if (!hostSubnet.hostIDs.length) {
|
|
66
|
+
return true;
|
|
67
|
+
} else if (isInSubnet(value, hostSubnet.subnet)) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return false;
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const vipBroadcastValidationSchema = (
|
|
76
|
+
{ machineNetworks }: NetworkConfigurationValues,
|
|
77
|
+
t: TFunction,
|
|
78
|
+
) =>
|
|
79
|
+
Yup.string().test(
|
|
80
|
+
'vip-no-broadcast',
|
|
81
|
+
t('ai:The IP address cannot be a network or broadcast address'),
|
|
82
|
+
function (value?: string) {
|
|
83
|
+
if (!value) {
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const vipAddress = getAddress(value)?.address;
|
|
88
|
+
if (!vipAddress) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const index = getArrayIndexFromPath(this.path || '');
|
|
93
|
+
const machineNetworkCidr = machineNetworks?.[index]?.cidr ?? machineNetworks?.[0]?.cidr ?? '';
|
|
94
|
+
if (!machineNetworkCidr) {
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const machineNetwork = getAddress(machineNetworkCidr);
|
|
99
|
+
if (!machineNetwork) {
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const machineNetworkBroadcast = machineNetwork.endAddress().address;
|
|
104
|
+
const machineNetworkAddress = machineNetwork.startAddress().address;
|
|
105
|
+
|
|
106
|
+
return vipAddress !== machineNetworkBroadcast && vipAddress !== machineNetworkAddress;
|
|
107
|
+
},
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
export const hostSubnetValidationSchema = Yup.string().when(['managedNetworkingType'], {
|
|
111
|
+
is: (managedNetworkingType: NetworkConfigurationValues['managedNetworkingType']) =>
|
|
112
|
+
managedNetworkingType === 'clusterManaged',
|
|
113
|
+
then: () => Yup.string().notOneOf([NO_SUBNET_SET], 'Host subnet must be selected.'),
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
export const vipNoSuffixValidationSchema = (
|
|
117
|
+
hostSubnets: HostSubnets,
|
|
118
|
+
values: NetworkConfigurationValues,
|
|
119
|
+
t: TFunction,
|
|
120
|
+
) =>
|
|
121
|
+
Yup.mixed().when(['vipDhcpAllocation', 'managedNetworkingType'], {
|
|
122
|
+
is: (
|
|
123
|
+
vipDhcpAllocation: NetworkConfigurationValues['vipDhcpAllocation'],
|
|
124
|
+
managedNetworkingType: NetworkConfigurationValues['managedNetworkingType'],
|
|
125
|
+
) => !vipDhcpAllocation && managedNetworkingType !== 'userManaged',
|
|
126
|
+
then: () => {
|
|
127
|
+
// Per-item schema for VIPs (apiVips[*].ip / ingressVips[*].ip)
|
|
128
|
+
// 1) Require value once set
|
|
129
|
+
// 2) Validate IP without suffix
|
|
130
|
+
// 3) Ensure VIP family matches machineNetworks[idx] family
|
|
131
|
+
// 4) Validate range vs selected subnets
|
|
132
|
+
// 5) No broadcast/network address
|
|
133
|
+
// 6) Uniqueness across API/Ingress
|
|
134
|
+
const vipFamilyMatchSchema = Yup.string().test(
|
|
135
|
+
'vip-family-match-machine-network',
|
|
136
|
+
t('ai:IP family must match the corresponding machine network family.'),
|
|
137
|
+
function (value?: string) {
|
|
138
|
+
if (!value) {
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
const index = getArrayIndexFromPath(this.path || '');
|
|
142
|
+
if (Number.isNaN(index)) {
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
const cidr = values.machineNetworks?.[index]?.cidr || '';
|
|
146
|
+
const mnIsV4 = isCIDR.v4(cidr);
|
|
147
|
+
const mnIsV6 = isCIDR.v6(cidr);
|
|
148
|
+
// If machine network at index is not selected/valid, don't block validation here
|
|
149
|
+
if (!mnIsV4 && !mnIsV6) {
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
const ipIsV4 = isIPv4Address(value);
|
|
153
|
+
const ipIsV6 = isIPv6Address(value);
|
|
154
|
+
if (!ipIsV4 && !ipIsV6) {
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
return mnIsV4 ? ipIsV4 : ipIsV6;
|
|
158
|
+
},
|
|
159
|
+
);
|
|
160
|
+
// Ensure API and Ingress VIPs at the same index are not the same
|
|
161
|
+
const vipUniqueSchema = Yup.string().test('vip-uniqueness', function (value?: string) {
|
|
162
|
+
if (!value) {
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
const index = getArrayIndexFromPath(this.path || '');
|
|
166
|
+
if (Number.isNaN(index)) {
|
|
167
|
+
return true;
|
|
168
|
+
}
|
|
169
|
+
const apiVip = values.apiVips?.[index]?.ip;
|
|
170
|
+
const ingressVip = values.ingressVips?.[index]?.ip;
|
|
171
|
+
if (!apiVip || !ingressVip) {
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
if (apiVip === ingressVip) {
|
|
175
|
+
return this.createError({
|
|
176
|
+
message: t('ai:The {{label}} Ingress and API IP addresses cannot be the same.', {
|
|
177
|
+
label: index === 0 ? t('ai:primary') : t('ai:secondary'),
|
|
178
|
+
}),
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
return true;
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
return alwaysRequired(t('ai:Required field'))
|
|
185
|
+
.concat(ipNoSuffixValidationSchema(t))
|
|
186
|
+
.concat(vipFamilyMatchSchema)
|
|
187
|
+
.concat(vipRangeValidationSchema(hostSubnets, values, false, t))
|
|
188
|
+
.concat(vipBroadcastValidationSchema(values, t))
|
|
189
|
+
.concat(vipUniqueSchema);
|
|
190
|
+
},
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
export const vipArrayValidationSchema = <T extends Yup.Maybe<Yup.AnyObject>>(
|
|
194
|
+
hostSubnets: HostSubnets,
|
|
195
|
+
values: NetworkConfigurationValues,
|
|
196
|
+
t: TFunction,
|
|
197
|
+
) =>
|
|
198
|
+
values.managedNetworkingType === 'clusterManaged'
|
|
199
|
+
? Yup.array<T>().of(
|
|
200
|
+
Yup.object({
|
|
201
|
+
clusterId: Yup.string(),
|
|
202
|
+
ip: vipNoSuffixValidationSchema(hostSubnets, values, t),
|
|
203
|
+
}),
|
|
204
|
+
)
|
|
205
|
+
: Yup.array<T>();
|
|
206
|
+
|
|
207
|
+
export const ipBlockValidationSchema = (
|
|
208
|
+
reservedCidrs: string | string[] | undefined,
|
|
209
|
+
t: TFunction,
|
|
210
|
+
) =>
|
|
211
|
+
Yup.string()
|
|
212
|
+
.required('A value is required.')
|
|
213
|
+
.test(
|
|
214
|
+
'valid-ip-address',
|
|
215
|
+
t(
|
|
216
|
+
'ai: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',
|
|
217
|
+
),
|
|
218
|
+
(value?: string): boolean => !!value && (isCIDR.v4(value) || isCIDR.v6(value)),
|
|
219
|
+
)
|
|
220
|
+
.test(
|
|
221
|
+
'valid-netmask',
|
|
222
|
+
t(
|
|
223
|
+
'ai: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.',
|
|
224
|
+
),
|
|
225
|
+
(value?: string) => {
|
|
226
|
+
const suffix = parseInt((value || '').split('/')[1]);
|
|
227
|
+
|
|
228
|
+
return (
|
|
229
|
+
(isCIDR.v4(value || '') && 0 < suffix && suffix < 26) ||
|
|
230
|
+
(isCIDR.v6(value || '') && 7 < suffix && suffix < 129)
|
|
231
|
+
);
|
|
232
|
+
},
|
|
233
|
+
)
|
|
234
|
+
.test(
|
|
235
|
+
'cidr-is-not-unspecified',
|
|
236
|
+
t(
|
|
237
|
+
'ai:The specified CIDR is invalid because its resulting routing prefix matches the unspecified address.',
|
|
238
|
+
),
|
|
239
|
+
(cidr: string) => {
|
|
240
|
+
const ip = getSubnet(cidr);
|
|
241
|
+
if (ip === null) {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// The first address is used to represent the network
|
|
246
|
+
const startAddress = ip.startAddress().address;
|
|
247
|
+
|
|
248
|
+
return startAddress !== IP_V4_ZERO && startAddress !== IP_V6_ZERO;
|
|
249
|
+
},
|
|
250
|
+
)
|
|
251
|
+
.test(
|
|
252
|
+
'valid-cidr-base-address',
|
|
253
|
+
({ value }) => t('ai:{{value}} is not a valid CIDR', { value: value as string }),
|
|
254
|
+
(cidr: string) => {
|
|
255
|
+
const ip = getSubnet(cidr);
|
|
256
|
+
if (ip === null) {
|
|
257
|
+
return false;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const networkAddress = ip.startAddress().parsedAddress;
|
|
261
|
+
const ipAddress = ip.parsedAddress;
|
|
262
|
+
const result = ipAddress.every((part, idx) => part === networkAddress[idx]);
|
|
263
|
+
|
|
264
|
+
return result;
|
|
265
|
+
},
|
|
266
|
+
)
|
|
267
|
+
.test('cidrs-can-not-overlap', t('ai:Provided CIDRs can not overlap.'), (cidr: string) => {
|
|
268
|
+
try {
|
|
269
|
+
if (cidr && reservedCidrs && reservedCidrs.length > 0) {
|
|
270
|
+
return !overlap(cidr, reservedCidrs);
|
|
271
|
+
}
|
|
272
|
+
} catch {
|
|
273
|
+
return false;
|
|
274
|
+
}
|
|
275
|
+
// passing by default
|
|
276
|
+
return true;
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
export const hostPrefixValidationSchema = (
|
|
280
|
+
clusterNetworkCidr: NetworkConfigurationValues['clusterNetworkCidr'],
|
|
281
|
+
t: TFunction,
|
|
282
|
+
) => {
|
|
283
|
+
const requiredText = t('ai:Required field');
|
|
284
|
+
const minMaxText = t(
|
|
285
|
+
'ai:The host prefix is a number between 1 and 32 for IPv4 and between 8 and 128 for IPv6.',
|
|
286
|
+
);
|
|
287
|
+
const netBlock = (clusterNetworkCidr || '').split('/')[1];
|
|
288
|
+
if (!netBlock) {
|
|
289
|
+
return Yup.number().required(requiredText).min(1, minMaxText).max(32, minMaxText);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
let netBlockNumber = parseInt(netBlock);
|
|
293
|
+
if (isNaN(netBlockNumber)) {
|
|
294
|
+
netBlockNumber = 1;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
const errorMsgPrefix = t(
|
|
298
|
+
'ai:The host prefix is a number between size of the cluster network CIDR range',
|
|
299
|
+
);
|
|
300
|
+
const errorMsgIPv4 = t('ai:{{errorMsgPrefix}} ({{netBlockNumber}}) and 25.', {
|
|
301
|
+
errorMsgPrefix,
|
|
302
|
+
netBlockNumber,
|
|
303
|
+
});
|
|
304
|
+
const errorMsgIPv6 = t('ai:{{errorMsgPrefix}} (8) and 128.', { errorMsgPrefix });
|
|
305
|
+
|
|
306
|
+
if (isCIDR.v6(clusterNetworkCidr || '')) {
|
|
307
|
+
return Yup.number().required(requiredText).min(8, errorMsgIPv6).max(128, errorMsgIPv6);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
if (isCIDR.v4(clusterNetworkCidr || '')) {
|
|
311
|
+
return Yup.number()
|
|
312
|
+
.required(requiredText)
|
|
313
|
+
.min(netBlockNumber, errorMsgIPv4)
|
|
314
|
+
.max(25, errorMsgIPv4);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
return Yup.number().required(requiredText);
|
|
318
|
+
};
|
|
319
|
+
|
|
320
|
+
export const day2ApiVipValidationSchema = (t: TFunction) =>
|
|
321
|
+
Yup.string().test(
|
|
322
|
+
'day2-api-vip',
|
|
323
|
+
t('ai:Provide a valid DNS name or IP Address'),
|
|
324
|
+
(value?: string) => {
|
|
325
|
+
if (!value) {
|
|
326
|
+
return true;
|
|
327
|
+
}
|
|
328
|
+
return isIPorDN(value);
|
|
329
|
+
},
|
|
330
|
+
);
|
|
331
|
+
|
|
332
|
+
export const bmcAddressValidationSchema = (t: TFunction) => {
|
|
333
|
+
return Yup.string()
|
|
334
|
+
.required()
|
|
335
|
+
.test(
|
|
336
|
+
'valid-bmc-address',
|
|
337
|
+
t(
|
|
338
|
+
'ai:The Value is not valid BMC address, supported protocols are redfish-virtualmedia or idrac-virtualmedia.',
|
|
339
|
+
),
|
|
340
|
+
(val) => {
|
|
341
|
+
try {
|
|
342
|
+
const url = parseUrl(val);
|
|
343
|
+
return ['redfish-virtualmedia', 'idrac-virtualmedia'].includes(url.protocol as string);
|
|
344
|
+
} catch (error) {
|
|
345
|
+
return false;
|
|
346
|
+
}
|
|
347
|
+
},
|
|
348
|
+
);
|
|
349
|
+
};
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { TFunction } from 'i18next';
|
|
2
|
+
import * as Yup from 'yup';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
CLUSTER_NAME_MAX_LENGTH,
|
|
6
|
+
clusterNameValidationMessages,
|
|
7
|
+
FORBIDDEN_HOSTNAMES,
|
|
8
|
+
hostnameValidationMessages,
|
|
9
|
+
locationValidationMessages,
|
|
10
|
+
nameValidationMessages,
|
|
11
|
+
} from './constants';
|
|
12
|
+
import { ClusterDetailsValues } from '../components';
|
|
13
|
+
import {
|
|
14
|
+
ALPHANUMERIC_REGEX,
|
|
15
|
+
CLUSTER_NAME_START_END_REGEX,
|
|
16
|
+
CLUSTER_NAME_VALID_CHARS_REGEX,
|
|
17
|
+
DNS_NAME_REGEX,
|
|
18
|
+
HOST_NAME_REGEX,
|
|
19
|
+
LOCATION_CHARS_REGEX,
|
|
20
|
+
NAME_CHARS_REGEX,
|
|
21
|
+
NAME_START_END_REGEX,
|
|
22
|
+
} from './regexes';
|
|
23
|
+
|
|
24
|
+
export const nameValidationSchema = (
|
|
25
|
+
t: TFunction,
|
|
26
|
+
usedClusterNames: string[],
|
|
27
|
+
baseDnsDomain = '',
|
|
28
|
+
validateUniqueName?: boolean,
|
|
29
|
+
isOcm = false,
|
|
30
|
+
) => {
|
|
31
|
+
const clusterNameValidationMessagesList = clusterNameValidationMessages(t);
|
|
32
|
+
return Yup.string()
|
|
33
|
+
.required(t('ai:Required field'))
|
|
34
|
+
.matches(CLUSTER_NAME_VALID_CHARS_REGEX, {
|
|
35
|
+
message: clusterNameValidationMessagesList.INVALID_VALUE,
|
|
36
|
+
excludeEmptyString: true,
|
|
37
|
+
})
|
|
38
|
+
.matches(CLUSTER_NAME_START_END_REGEX, {
|
|
39
|
+
message: clusterNameValidationMessagesList.INVALID_START_END,
|
|
40
|
+
excludeEmptyString: true,
|
|
41
|
+
})
|
|
42
|
+
.min(
|
|
43
|
+
isOcm ? 1 : 2,
|
|
44
|
+
isOcm
|
|
45
|
+
? clusterNameValidationMessagesList.INVALID_LENGTH_OCM
|
|
46
|
+
: clusterNameValidationMessagesList.INVALID_LENGTH_ACM,
|
|
47
|
+
)
|
|
48
|
+
.max(
|
|
49
|
+
CLUSTER_NAME_MAX_LENGTH,
|
|
50
|
+
isOcm
|
|
51
|
+
? clusterNameValidationMessagesList.INVALID_LENGTH_OCM
|
|
52
|
+
: clusterNameValidationMessagesList.INVALID_LENGTH_ACM,
|
|
53
|
+
)
|
|
54
|
+
.when('useRedHatDnsService', {
|
|
55
|
+
is: (useRedHatDnsService: ClusterDetailsValues['useRedHatDnsService']) =>
|
|
56
|
+
useRedHatDnsService === true,
|
|
57
|
+
then: (schema) =>
|
|
58
|
+
schema.test(
|
|
59
|
+
'is-name-unique',
|
|
60
|
+
clusterNameValidationMessagesList.NOT_UNIQUE,
|
|
61
|
+
(value?: string) => {
|
|
62
|
+
const clusterFullName = `${value || ''}.${baseDnsDomain}`;
|
|
63
|
+
return !value || !usedClusterNames.includes(clusterFullName);
|
|
64
|
+
},
|
|
65
|
+
),
|
|
66
|
+
otherwise: (schema) =>
|
|
67
|
+
schema.test(
|
|
68
|
+
'is-name-unique',
|
|
69
|
+
clusterNameValidationMessagesList.NOT_UNIQUE,
|
|
70
|
+
(value?: string) => {
|
|
71
|
+
// in CIM cluster name is ClusterDeployment CR name which must be unique
|
|
72
|
+
return validateUniqueName ? !value || !usedClusterNames.includes(value) : true;
|
|
73
|
+
},
|
|
74
|
+
),
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const richNameValidationSchema = (t: TFunction, usedNames: string[], origName?: string) => {
|
|
79
|
+
const nameValidationMessagesList = nameValidationMessages(t);
|
|
80
|
+
return Yup.string()
|
|
81
|
+
.min(1, nameValidationMessagesList.INVALID_LENGTH)
|
|
82
|
+
.max(253, nameValidationMessagesList.INVALID_LENGTH)
|
|
83
|
+
.test(
|
|
84
|
+
nameValidationMessagesList.INVALID_START_END,
|
|
85
|
+
nameValidationMessagesList.INVALID_START_END,
|
|
86
|
+
(value?: string) => {
|
|
87
|
+
const trimmed = value?.trim();
|
|
88
|
+
if (!trimmed) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
return (
|
|
92
|
+
!!trimmed[0].match(NAME_START_END_REGEX) &&
|
|
93
|
+
(trimmed[trimmed.length - 1]
|
|
94
|
+
? !!trimmed[trimmed.length - 1].match(NAME_START_END_REGEX)
|
|
95
|
+
: true)
|
|
96
|
+
);
|
|
97
|
+
},
|
|
98
|
+
)
|
|
99
|
+
.matches(HOST_NAME_REGEX, nameValidationMessagesList.INVALID_FORMAT)
|
|
100
|
+
.matches(NAME_CHARS_REGEX, {
|
|
101
|
+
message: nameValidationMessagesList.INVALID_VALUE,
|
|
102
|
+
excludeEmptyString: true,
|
|
103
|
+
})
|
|
104
|
+
.test(nameValidationMessagesList.NOT_UNIQUE, nameValidationMessagesList.NOT_UNIQUE, (value) => {
|
|
105
|
+
if (!value || value === origName) {
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
return !usedNames.find((n) => n === value);
|
|
109
|
+
})
|
|
110
|
+
.notOneOf(FORBIDDEN_HOSTNAMES, hostnameValidationMessages(t).LOCALHOST_ERR);
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export const dnsNameValidationSchema = (t: TFunction) =>
|
|
114
|
+
Yup.string()
|
|
115
|
+
.test(
|
|
116
|
+
'dns-name-label-length',
|
|
117
|
+
t('ai:Single label of the DNS name can not be longer than 63 characters.'),
|
|
118
|
+
(value?: string) => (value || '').split('.').every((label: string) => label.length <= 63),
|
|
119
|
+
)
|
|
120
|
+
.matches(DNS_NAME_REGEX, {
|
|
121
|
+
message: (value) =>
|
|
122
|
+
t('ai:Value "{{value}}" is not valid DNS name. Example: basedomain.example.com', { value }),
|
|
123
|
+
excludeEmptyString: true,
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
export const baseDomainValidationSchema = (t: TFunction) =>
|
|
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
|
+
}
|
|
137
|
+
|
|
138
|
+
// Check the label lengths
|
|
139
|
+
const labels = (value || '').split('.');
|
|
140
|
+
return labels.every((label: string) => label.length <= 63);
|
|
141
|
+
},
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
export const locationValidationSchema = (t: TFunction) =>
|
|
145
|
+
Yup.string()
|
|
146
|
+
.min(1, locationValidationMessages(t).INVALID_LENGTH)
|
|
147
|
+
.max(63, locationValidationMessages(t).INVALID_LENGTH)
|
|
148
|
+
.test(
|
|
149
|
+
locationValidationMessages(t).INVALID_START_END,
|
|
150
|
+
locationValidationMessages(t).INVALID_START_END,
|
|
151
|
+
(value?: string) => {
|
|
152
|
+
const trimmed = value?.trim();
|
|
153
|
+
if (!trimmed) {
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
return (
|
|
157
|
+
!!trimmed[0].match(ALPHANUMERIC_REGEX) &&
|
|
158
|
+
(trimmed[trimmed.length - 1]
|
|
159
|
+
? !!trimmed[trimmed.length - 1].match(ALPHANUMERIC_REGEX)
|
|
160
|
+
: true)
|
|
161
|
+
);
|
|
162
|
+
},
|
|
163
|
+
)
|
|
164
|
+
.matches(LOCATION_CHARS_REGEX, {
|
|
165
|
+
message: locationValidationMessages(t).INVALID_VALUE,
|
|
166
|
+
excludeEmptyString: true,
|
|
167
|
+
})
|
|
168
|
+
.required(t('ai:Location is a required field.'));
|
|
@@ -57,12 +57,6 @@ export const locationValidationMessages = (t: TFunction) => ({
|
|
|
57
57
|
INVALID_START_END: t('ai:Must start and end with an alphanumeric character'),
|
|
58
58
|
});
|
|
59
59
|
|
|
60
|
-
export const bmcAddressValidationMessages = (t: TFunction) => ({
|
|
61
|
-
INVALID_VALUE: t(
|
|
62
|
-
'ai:The Value is not valid BMC address, supported protocols are redfish-virtualmedia or idrac-virtualmedia.',
|
|
63
|
-
),
|
|
64
|
-
});
|
|
65
|
-
|
|
66
60
|
export const FORBIDDEN_HOSTNAMES = [
|
|
67
61
|
'localhost',
|
|
68
62
|
'localhost.localdomain',
|
|
@@ -71,3 +65,6 @@ export const FORBIDDEN_HOSTNAMES = [
|
|
|
71
65
|
'localhost6',
|
|
72
66
|
'localhost6.localdomain6',
|
|
73
67
|
];
|
|
68
|
+
|
|
69
|
+
export const getIncorrectFileTypeMessage = (t: TFunction) =>
|
|
70
|
+
t('ai:File type is not supported. File type must be yaml, yml, json, yaml.patch. or yml.patch.');
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import * as Yup from 'yup';
|
|
2
|
+
import { TFunction } from 'i18next';
|
|
3
|
+
import { FORBIDDEN_HOSTNAMES, hostnameValidationMessages } from './constants';
|
|
4
|
+
import { NAME_START_END_REGEX, NAME_CHARS_REGEX } from './regexes';
|
|
5
|
+
|
|
6
|
+
export const richHostnameValidationSchema = (
|
|
7
|
+
t: TFunction,
|
|
8
|
+
usedNames: string[],
|
|
9
|
+
origName?: string,
|
|
10
|
+
) => {
|
|
11
|
+
const hostnameValidationMessagesList = hostnameValidationMessages(t);
|
|
12
|
+
return Yup.string()
|
|
13
|
+
.min(1, hostnameValidationMessagesList.INVALID_LENGTH)
|
|
14
|
+
.max(63, hostnameValidationMessagesList.INVALID_LENGTH)
|
|
15
|
+
.test(
|
|
16
|
+
hostnameValidationMessagesList.INVALID_START_END,
|
|
17
|
+
hostnameValidationMessagesList.INVALID_START_END,
|
|
18
|
+
(value?: string) => {
|
|
19
|
+
const trimmed = value?.trim();
|
|
20
|
+
if (!trimmed) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
return (
|
|
24
|
+
!!trimmed[0].match(NAME_START_END_REGEX) &&
|
|
25
|
+
(trimmed[trimmed.length - 1]
|
|
26
|
+
? !!trimmed[trimmed.length - 1].match(NAME_START_END_REGEX)
|
|
27
|
+
: true)
|
|
28
|
+
);
|
|
29
|
+
},
|
|
30
|
+
)
|
|
31
|
+
.matches(NAME_CHARS_REGEX, {
|
|
32
|
+
message: hostnameValidationMessagesList.INVALID_VALUE,
|
|
33
|
+
excludeEmptyString: true,
|
|
34
|
+
})
|
|
35
|
+
.test(
|
|
36
|
+
hostnameValidationMessagesList.NOT_UNIQUE,
|
|
37
|
+
hostnameValidationMessagesList.NOT_UNIQUE,
|
|
38
|
+
(value) => {
|
|
39
|
+
if (!value || value === origName) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
return !usedNames.find((n) => n === value);
|
|
43
|
+
},
|
|
44
|
+
)
|
|
45
|
+
.notOneOf(FORBIDDEN_HOSTNAMES, hostnameValidationMessagesList.LOCALHOST_ERR);
|
|
46
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export * from './addressValidation';
|
|
2
|
+
export * from './clusterDetailsValidation';
|
|
3
|
+
export * from './hostnameValidation';
|
|
4
|
+
export * from './networkingValidation';
|
|
5
|
+
export * from './ntpValidation';
|
|
6
|
+
export * from './proxyValidation';
|
|
7
|
+
export * from './pullSecretValidation';
|
|
8
|
+
export * from './sshValidation';
|
|
9
|
+
|
|
10
|
+
export * from './constants';
|
|
11
|
+
export { ALPHANUMERIC_REGEX, LOCATION_CHARS_REGEX } from './regexes';
|