From 4417c412e868cebfe2f59fc4459d05753c11ef2a Mon Sep 17 00:00:00 2001 From: Sharon Gratch Date: Wed, 17 Apr 2024 09:20:13 +0300 Subject: [PATCH] Use dynamic validations for providers fields Replace all static providers fields validations with dynamic ones based on the provider validators. This fix all providers for both create and edit credentials dialogs. Signed-off-by: Sharon Gratch --- .../openshiftSecretFieldValidator.ts | 27 ++++-- .../openshift/validateOpenshiftURL.ts | 10 +- .../openstackSecretFieldValidator.ts | 97 ++++++++++++++++++- .../openstack/openstackSecretValidator.ts | 2 +- .../openstack/validateOpenstackURL.ts | 17 +++- .../provider/ova/validateOvaNfsPath.ts | 10 +- .../ovirt/ovirtSecretFieldValidator.ts | 38 +++++++- .../provider/ovirt/validateOvirtURL.ts | 10 +- .../vsphere/esxiSecretFieldValidator.ts | 21 +++- .../provider/vsphere/validateEsxiURL.ts | 3 +- .../provider/vsphere/validateVCenterURL.ts | 3 +- .../provider/vsphere/validateVDDKImage.ts | 3 +- .../vsphere/vcenterSecretFieldValidator.ts | 21 +++- .../components/EsxiProviderCreateForm.tsx | 2 +- .../components/OVAProviderCreateForm.tsx | 11 +-- .../OpenshiftProviderCreateForm.tsx | 9 +- .../OpenstackProviderCreateForm.tsx | 11 +-- .../components/OvirtProviderCreateForm.tsx | 11 +-- .../components/edit/EsxiCredentialsEdit.tsx | 14 +-- .../edit/OpenshiftCredentialsEdit.tsx | 31 +++--- .../edit/OpenstackCredentialsEdit.tsx | 35 +++---- ...ionCredentialNameSecretFieldsFormGroup.tsx | 46 ++++----- .../ApplicationWithCredentialsIDFormGroup.tsx | 32 +++--- .../PasswordSecretFieldsFormGroup.tsx | 28 +++--- .../TokenWithUserIDSecretFieldsFormGroup.tsx | 21 ++-- ...TokenWithUsernameSecretFieldsFormGroup.tsx | 25 +++-- .../components/edit/OvirtCredentialsEdit.tsx | 37 +++---- .../edit/VCenterCredentialsEdit.tsx | 14 +-- 28 files changed, 379 insertions(+), 210 deletions(-) diff --git a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/openshift/openshiftSecretFieldValidator.ts b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/openshift/openshiftSecretFieldValidator.ts index 5f5494252..7a351b0f4 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/openshift/openshiftSecretFieldValidator.ts +++ b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/openshift/openshiftSecretFieldValidator.ts @@ -16,7 +16,7 @@ import { validateK8sToken, validatePublicCert, ValidationMsg } from '../../commo * Validation msg and description should add information about the validation type. */ export const openshiftSecretFieldValidator = (id: string, value: string): ValidationMsg => { - const trimmedValue = value.trim(); + const trimmedValue = value?.trim(); let validationMsg: ValidationMsg; @@ -25,7 +25,7 @@ export const openshiftSecretFieldValidator = (id: string, value: string): Valida validationMsg = validateToken(trimmedValue); break; case 'insecureSkipVerify': - validationMsg = { type: 'default', msg: 'Migrate without validating a CA certificate' }; + validationMsg = validateInsecureSkipVerify(trimmedValue); break; case 'cacert': validationMsg = validateCacert(trimmedValue); @@ -41,17 +41,17 @@ export const openshiftSecretFieldValidator = (id: string, value: string): Valida const validateToken = (value: string): ValidationMsg => { const valid = validateK8sToken(value); - if (value === '') { + if (value === undefined || value === '') { return { type: 'default', - msg: 'A service account token, required for authenticating the the connection to the API server.', + msg: 'A service account token, optional, used for authenticating the the connection to the API server.', }; } if (valid) { return { type: 'success', - msg: 'A service account token, required for authenticating the the connection to the API server.', + msg: 'A service account token, optional, used for authenticating the the connection to the API server.', }; } @@ -64,7 +64,7 @@ const validateToken = (value: string): ValidationMsg => { const validateCacert = (value: string): ValidationMsg => { const valid = validatePublicCert(value); - if (value === '') { + if (value === undefined || value === '') { return { type: 'default', msg: 'The Manager CA certificate unless it was replaced by a third-party certificate, in which case, enter the Manager Apache CA certificate.', @@ -83,3 +83,18 @@ const validateCacert = (value: string): ValidationMsg => { msg: 'Invalid CA certificate, certificate must be in a valid PEM encoded X.509 format.', }; }; + +const validateInsecureSkipVerify = (value: string): ValidationMsg => { + // For a newly opened form where the field is not set yet, set the validation type to default. + if (value === undefined) { + return { type: 'default', msg: 'Migrate without validating a CA certificate' }; + } + + const valid = ['true', 'false', ''].includes(value); + + if (valid) { + return { type: 'success', msg: 'Migrate without validating a CA certificate' }; + } + + return { type: 'error', msg: 'Invalid Skip certificate validation value, must be true or false' }; +}; diff --git a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/openshift/validateOpenshiftURL.ts b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/openshift/validateOpenshiftURL.ts index c50c8e316..a5dc905f7 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/openshift/validateOpenshiftURL.ts +++ b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/openshift/validateOpenshiftURL.ts @@ -1,12 +1,20 @@ import { validateURL, ValidationMsg } from '../../common'; export const validateOpenshiftURL = (url: string | number): ValidationMsg => { + // For a newly opened form where the field is not set yet, set the validation type to default. + if (url === undefined) { + return { + type: 'default', + msg: 'The URL of the Openshift Virtualization API endpoint, for example: https://example.com:6443 .', + }; + } + // Sanity check if (typeof url !== 'string') { return { type: 'error', msg: 'URL is not a string' }; } - const trimmedUrl: string = url.toString().trim(); + const trimmedUrl: string = url.trim(); const isValidURL = validateURL(trimmedUrl); if (trimmedUrl === '') { diff --git a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/openstack/openstackSecretFieldValidator.ts b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/openstack/openstackSecretFieldValidator.ts index 8dc0ca3fd..5a6576298 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/openstack/openstackSecretFieldValidator.ts +++ b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/openstack/openstackSecretFieldValidator.ts @@ -67,6 +67,14 @@ export const openstackSecretFieldValidator = (id: string, value: string): Valida const validateUsername = (value: string): ValidationMsg => { const valid = validateNoSpaces(value); + // For a newly opened form where the field is not set yet, set the validation type to default. + if (value === undefined) { + return { + type: 'default', + msg: 'A username for connecting to the OpenStack Identity (Keystone) endpoint. [required]', + }; + } + if (value === '') { return { type: 'error', @@ -87,6 +95,14 @@ const validateUsername = (value: string): ValidationMsg => { const validatePassword = (value: string): ValidationMsg => { const valid = validateNoSpaces(value); + // For a newly opened form where the field is not set yet, set the validation type to default. + if (value === undefined) { + return { + type: 'default', + msg: 'A user password for connecting to the OpenStack Identity (Keystone) endpoint. [required]', + }; + } + if (value === '') { return { type: 'error', @@ -107,6 +123,14 @@ const validatePassword = (value: string): ValidationMsg => { const validateRegionName = (value: string): ValidationMsg => { const valid = validateNoSpaces(value); + // For a newly opened form where the field is not set yet, set the validation type to default. + if (value === undefined) { + return { + type: 'default', + msg: 'OpenStack region name. [required]', + }; + } + if (value === '') { return { type: 'error', @@ -124,6 +148,14 @@ const validateRegionName = (value: string): ValidationMsg => { const validateProjectName = (value: string): ValidationMsg => { const valid = validateNoSpaces(value); + // For a newly opened form where the field is not set yet, set the validation type to default. + if (value === undefined) { + return { + type: 'default', + msg: 'OpenStack project name. [required]', + }; + } + if (value === '') { return { type: 'error', @@ -141,6 +173,14 @@ const validateProjectName = (value: string): ValidationMsg => { const validateDomainName = (value: string): ValidationMsg => { const valid = validateNoSpaces(value); + // For a newly opened form where the field is not set yet, set the validation type to default. + if (value === undefined) { + return { + type: 'default', + msg: 'OpenStack domain name. [required]', + }; + } + if (value === '') { return { type: 'error', @@ -158,6 +198,14 @@ const validateDomainName = (value: string): ValidationMsg => { const validateToken = (value: string): ValidationMsg => { const valid = validateNoSpaces(value); + // For a newly opened form where the field is not set yet, set the validation type to default. + if (value === undefined) { + return { + type: 'default', + msg: 'OpenStack token for authentication using a user name. [required]', + }; + } + if (value === '') { return { type: 'error', @@ -175,6 +223,14 @@ const validateToken = (value: string): ValidationMsg => { const validateUserID = (value: string): ValidationMsg => { const valid = validateNoSpaces(value); + // For a newly opened form where the field is not set yet, set the validation type to default. + if (value === undefined) { + return { + type: 'default', + msg: 'A user ID for connecting to the OpenStack Identity (Keystone) endpoint. [required]', + }; + } + if (value === '') { return { type: 'error', @@ -195,6 +251,14 @@ const validateUserID = (value: string): ValidationMsg => { const validateProjectID = (value: string): ValidationMsg => { const valid = validateNoSpaces(value); + // For a newly opened form where the field is not set yet, set the validation type to default. + if (value === undefined) { + return { + type: 'default', + msg: 'OpenStack project ID. [required]', + }; + } + if (value === '') { return { type: 'error', @@ -212,6 +276,14 @@ const validateProjectID = (value: string): ValidationMsg => { const validateApplicationCredentialID = (value: string): ValidationMsg => { const valid = validateNoSpaces(value); + // For a newly opened form where the field is not set yet, set the validation type to default. + if (value === undefined) { + return { + type: 'default', + msg: 'OpenStack application credential ID needed for the application credential authentication. [required]', + }; + } + if (value === '') { return { type: 'error', @@ -232,6 +304,14 @@ const validateApplicationCredentialID = (value: string): ValidationMsg => { const validateApplicationCredentialSecret = (value: string): ValidationMsg => { const valid = validateNoSpaces(value); + // For a newly opened form where the field is not set yet, set the validation type to default. + if (value === undefined) { + return { + type: 'default', + msg: 'OpenStack application credential Secret needed for the application credential authentication. [required]', + }; + } + if (value === '') { return { type: 'error', @@ -252,6 +332,14 @@ const validateApplicationCredentialSecret = (value: string): ValidationMsg => { const validateApplicationCredentialName = (value: string): ValidationMsg => { const valid = validateNoSpaces(value); + // For a newly opened form where the field is not set yet, set the validation type to default. + if (value === undefined) { + return { + type: 'default', + msg: 'OpenStack application credential name needed for application credential authentication. [required]', + }; + } + if (value === '') { return { type: 'error', @@ -270,19 +358,24 @@ const validateApplicationCredentialName = (value: string): ValidationMsg => { }; const validateInsecureSkipVerify = (value: string): ValidationMsg => { + // For a newly opened form where the field is not set yet, set the validation type to default. + if (value === undefined) { + return { type: 'default', msg: 'Migrate without validating a CA certificate' }; + } + const valid = ['true', 'false', ''].includes(value); if (valid) { return { type: 'success', msg: 'Migrate without validating a CA certificate' }; } - return { type: 'error', msg: 'Invalid skip verify flag, must be true or false' }; + return { type: 'error', msg: 'Invalid Skip certificate validation value, must be true or false' }; }; const validateCacert = (value: string): ValidationMsg => { const valid = validatePublicCert(value); - if (value === '') { + if (value === undefined || value === '') { return { type: 'default', msg: 'The Manager CA certificate unless it was replaced by a third-party certificate, in which case, enter the Manager Apache CA certificate.', diff --git a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/openstack/openstackSecretValidator.ts b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/openstack/openstackSecretValidator.ts index df8ed11a4..0b8c39411 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/openstack/openstackSecretValidator.ts +++ b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/openstack/openstackSecretValidator.ts @@ -86,7 +86,7 @@ export function openstackSecretValidator(secret: IoK8sApiCoreV1Secret): Validati } // Add ca cert validation if not insecureSkipVerify - const insecureSkipVerify = safeBase64Decode(secret?.data?.['insecureSkipVerify'] || ''); + const insecureSkipVerify = safeBase64Decode(secret?.data?.['insecureSkipVerify']); if (insecureSkipVerify !== 'true') { validateFields.push('cacert'); } diff --git a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/openstack/validateOpenstackURL.ts b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/openstack/validateOpenstackURL.ts index e871bea7b..1d9168937 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/openstack/validateOpenstackURL.ts +++ b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/openstack/validateOpenstackURL.ts @@ -1,14 +1,29 @@ import { validateURL, ValidationMsg } from '../../common'; export const validateOpenstackURL = (url: string | number): ValidationMsg => { + // For a newly opened form where the field is not set yet, set the validation type to default. + if (url === undefined) { + return { + type: 'default', + msg: 'The URL is required, URL of the OpenStack Identity (Keystone) API endpoint, for example: https://identity_service.com:5000/v3 .', + }; + } + // Sanity check if (typeof url !== 'string') { return { type: 'error', msg: 'URL is not a string' }; } - const trimmedUrl: string = url.toString().trim(); + const trimmedUrl: string = url.trim(); const isValidURL = validateURL(trimmedUrl); + if (trimmedUrl === '') { + return { + type: 'error', + msg: 'The URL is required, URL of the OpenStack Identity (Keystone) API endpoint, for example: https://identity_service.com:5000/v3 .', + }; + } + if (!isValidURL) { return { type: 'error', diff --git a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/ova/validateOvaNfsPath.ts b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/ova/validateOvaNfsPath.ts index cc82320bd..2bb218302 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/ova/validateOvaNfsPath.ts +++ b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/ova/validateOvaNfsPath.ts @@ -1,12 +1,20 @@ import { validateNFSMount, ValidationMsg } from '../../common'; export const validateOvaNfsPath = (url: string | number): ValidationMsg => { + // For a newly opened form where the field is not set yet, set the validation type to default. + if (url === undefined) { + return { + type: 'default', + msg: 'The NFS shared directory containing the Open Virtual Appliance (OVA) files, for example: 10.10.0.10:/ova .', + }; + } + // Sanity check if (typeof url !== 'string') { return { type: 'error', msg: 'URL is not a string' }; } - const trimmedUrl: string = url.toString().trim(); + const trimmedUrl: string = url.trim(); const isValidURL = validateNFSMount(trimmedUrl); if (trimmedUrl === '') { diff --git a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/ovirt/ovirtSecretFieldValidator.ts b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/ovirt/ovirtSecretFieldValidator.ts index c0c5a0def..e7f319cff 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/ovirt/ovirtSecretFieldValidator.ts +++ b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/ovirt/ovirtSecretFieldValidator.ts @@ -18,7 +18,7 @@ import { * 'error' - The field's value has failed validation. */ export const ovirtSecretFieldValidator = (id: string, value: string): ValidationMsg => { - const trimmedValue = value.trim(); + const trimmedValue = value?.trim(); let validationState: ValidationMsg; @@ -30,7 +30,7 @@ export const ovirtSecretFieldValidator = (id: string, value: string): Validation validationState = validatePassword(trimmedValue); break; case 'insecureSkipVerify': - validationState = { type: 'default', msg: 'Migrate without validating a CA certificate' }; + validationState = validateInsecureSkipVerify(trimmedValue); break; case 'cacert': validationState = validateCacert(trimmedValue); @@ -46,6 +46,14 @@ export const ovirtSecretFieldValidator = (id: string, value: string): Validation const validateUser = (value: string): ValidationMsg => { const noSpaces = validateNoSpaces(value); + // For a newly opened form where the field is not set yet, set the validation type to default. + if (value === undefined) { + return { + type: 'default', + msg: 'A username for connecting to the Red Hat Virtualization Manager (RHVM) API endpoint, for example: name@internal . [required]', + }; + } + if (value === '') { return { type: 'error', @@ -75,6 +83,14 @@ const validateUser = (value: string): ValidationMsg => { const validatePassword = (value: string): ValidationMsg => { const valid = validateNoSpaces(value); + // For a newly opened form where the field is not set yet, set the validation type to default. + if (value === undefined) { + return { + type: 'default', + msg: 'User name password is required, user password for connecting to the Red Hat Virtualization Manager (RHVM) API endpoint.', + }; + } + if (value === '') { return { type: 'error', @@ -95,7 +111,8 @@ const validatePassword = (value: string): ValidationMsg => { const validateCacert = (value: string): ValidationMsg => { const valid = validatePublicCert(value); - if (value === '') { + // For a newly opened form where the field is not set yet, set the validation type to default. + if (value === undefined || value === '') { return { type: 'default', msg: 'The Manager CA certificate unless it was replaced by a third-party certificate, in which case, enter the Manager Apache CA certificate.', @@ -114,3 +131,18 @@ const validateCacert = (value: string): ValidationMsg => { msg: 'Invalid CA certificate, certificate must be in a valid PEM encoded X.509 format.', }; }; + +const validateInsecureSkipVerify = (value: string): ValidationMsg => { + // For a newly opened form where the field is not set yet, set the validation type to default. + if (value === undefined) { + return { type: 'default', msg: 'Migrate without validating a CA certificate' }; + } + + const valid = ['true', 'false', ''].includes(value); + + if (valid) { + return { type: 'success', msg: 'Migrate without validating a CA certificate' }; + } + + return { type: 'error', msg: 'Invalid Skip certificate validation value, must be true or false' }; +}; diff --git a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/ovirt/validateOvirtURL.ts b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/ovirt/validateOvirtURL.ts index e33ffe4b2..2f183f3ef 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/ovirt/validateOvirtURL.ts +++ b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/ovirt/validateOvirtURL.ts @@ -1,12 +1,20 @@ import { validateURL, ValidationMsg } from '../../common'; export const validateOvirtURL = (url: string | number): ValidationMsg => { + // For a newly opened form where the field is not set yet, set the validation type to default. + if (url === undefined) { + return { + type: 'default', + msg: 'The URL of the Red Hat Virtualization Manager (RHVM) API endpoint, for example: https://rhv-host-example.com/ovirt-engine/api .', + }; + } + // Sanity check if (typeof url !== 'string') { return { type: 'error', msg: 'URL is not a string' }; } - const trimmedUrl: string = url.toString().trim(); + const trimmedUrl: string = url.trim(); const isValidURL = validateURL(trimmedUrl); if (trimmedUrl === '') { diff --git a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/vsphere/esxiSecretFieldValidator.ts b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/vsphere/esxiSecretFieldValidator.ts index e7e33e866..40aaa25b5 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/vsphere/esxiSecretFieldValidator.ts +++ b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/vsphere/esxiSecretFieldValidator.ts @@ -25,7 +25,7 @@ export const esxiSecretFieldValidator = (id: string, value: string): ValidationM validationState = validatePassword(trimmedValue); break; case 'insecureSkipVerify': - validationState = { type: 'default', msg: 'Migrate without validating a CA certificate' }; + validationState = validateInsecureSkipVerify(trimmedValue); break; case 'cacert': validationState = validateCacert(trimmedValue); @@ -41,6 +41,7 @@ export const esxiSecretFieldValidator = (id: string, value: string): ValidationM const validateUser = (value: string): ValidationMsg => { const noSpaces = validateNoSpaces(value); + // For a newly opened form where the field is not set yet, set the validation type to default. if (value === undefined) { return { type: 'default', @@ -68,6 +69,7 @@ const validateUser = (value: string): ValidationMsg => { const validatePassword = (value: string): ValidationMsg => { const valid = validateNoSpaces(value); + // For a newly opened form where the field is not set yet, set the validation type to default. if (value === undefined) { return { type: 'default', @@ -89,10 +91,25 @@ const validatePassword = (value: string): ValidationMsg => { return { type: 'error', msg: 'Invalid password, spaces are not allowed' }; }; +const validateInsecureSkipVerify = (value: string): ValidationMsg => { + // For a newly opened form where the field is not set yet, set the validation type to default. + if (value === undefined) { + return { type: 'default', msg: 'Migrate without validating a CA certificate' }; + } + + const valid = ['true', 'false', ''].includes(value); + + if (valid) { + return { type: 'success', msg: 'Migrate without validating a CA certificate' }; + } + + return { type: 'error', msg: 'Invalid Skip certificate validation value, must be true or false' }; +}; + const validateCacert = (value: string): ValidationMsg => { const valid = validatePublicCert(value); - if (value === '') { + if (value === undefined || value === '') { return { type: 'default', msg: 'The Manager CA certificate unless it was replaced by a third-party certificate, in which case, enter the Manager Apache CA certificate.', diff --git a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/vsphere/validateEsxiURL.ts b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/vsphere/validateEsxiURL.ts index 41797f644..0cf0a59be 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/vsphere/validateEsxiURL.ts +++ b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/vsphere/validateEsxiURL.ts @@ -1,6 +1,7 @@ import { validateURL, ValidationMsg } from '../../common'; export const validateEsxiURL = (url: string | number): ValidationMsg => { + // For a newly opened form where the field is not set yet, set the validation type to default. if (url === undefined) { return { type: 'default', @@ -13,7 +14,7 @@ export const validateEsxiURL = (url: string | number): ValidationMsg => { return { type: 'error', msg: 'URL is not a string' }; } - const trimmedUrl: string = url.toString().trim(); + const trimmedUrl: string = url.trim(); const isValidURL = validateURL(trimmedUrl); if (trimmedUrl === '') { diff --git a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/vsphere/validateVCenterURL.ts b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/vsphere/validateVCenterURL.ts index 86fc1cf49..041290776 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/vsphere/validateVCenterURL.ts +++ b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/vsphere/validateVCenterURL.ts @@ -1,6 +1,7 @@ import { validateURL, ValidationMsg } from '../../common'; export const validateVCenterURL = (url: string | number): ValidationMsg => { + // For a newly opened form where the field is not set yet, set the validation type to default. if (url === undefined) { return { type: 'default', @@ -13,7 +14,7 @@ export const validateVCenterURL = (url: string | number): ValidationMsg => { return { type: 'error', msg: 'URL is not a string' }; } - const trimmedUrl: string = url.toString().trim(); + const trimmedUrl: string = url.trim(); const isValidURL = validateURL(trimmedUrl); if (trimmedUrl === '') { diff --git a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/vsphere/validateVDDKImage.ts b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/vsphere/validateVDDKImage.ts index 538039131..6f97a2e12 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/vsphere/validateVDDKImage.ts +++ b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/vsphere/validateVDDKImage.ts @@ -1,6 +1,7 @@ import { validateContainerImage, ValidationMsg } from '../../common'; export const validateVDDKImage = (vddkImage: string | number): ValidationMsg => { + // For a newly opened form where the field is not set yet, set the validation type to default. if (vddkImage === undefined) return { msg: 'The VDDK image is empty, it is recommended to provide an image, for example: quay.io/kubev2v/vddk:latest .', @@ -12,7 +13,7 @@ export const validateVDDKImage = (vddkImage: string | number): ValidationMsg => return { type: 'error', msg: 'VDDK image is not a string' }; } - const trimmedVddkImage: string = vddkImage.toString().trim(); + const trimmedVddkImage: string = vddkImage.trim(); const isValidTrimmedVddkImage = validateContainerImage(trimmedVddkImage); if (trimmedVddkImage === '') diff --git a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/vsphere/vcenterSecretFieldValidator.ts b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/vsphere/vcenterSecretFieldValidator.ts index 20044662a..84d913e1d 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/vsphere/vcenterSecretFieldValidator.ts +++ b/packages/forklift-console-plugin/src/modules/Providers/utils/validators/provider/vsphere/vcenterSecretFieldValidator.ts @@ -30,7 +30,7 @@ export const vcenterSecretFieldValidator = (id: string, value: string): Validati validationState = validatePassword(trimmedValue); break; case 'insecureSkipVerify': - validationState = { type: 'default', msg: 'Migrate without validating a CA certificate' }; + validationState = validateInsecureSkipVerify(trimmedValue); break; case 'cacert': validationState = validateCacert(trimmedValue); @@ -46,6 +46,7 @@ export const vcenterSecretFieldValidator = (id: string, value: string): Validati const validateUser = (value: string): ValidationMsg => { const noSpaces = validateNoSpaces(value); + // For a newly opened form where the field is not set yet, set the validation type to default. if (value === undefined) { return { type: 'default', @@ -82,6 +83,7 @@ const validateUser = (value: string): ValidationMsg => { const validatePassword = (value: string): ValidationMsg => { const valid = validateNoSpaces(value); + // For a newly opened form where the field is not set yet, set the validation type to default. if (value === undefined) { return { type: 'default', @@ -106,7 +108,7 @@ const validatePassword = (value: string): ValidationMsg => { const validateCacert = (value: string): ValidationMsg => { const valid = validatePublicCert(value); - if (value === '') { + if (value === undefined || value === '') { return { type: 'default', msg: 'The Manager CA certificate unless it was replaced by a third-party certificate, in which case, enter the Manager Apache CA certificate.', @@ -125,3 +127,18 @@ const validateCacert = (value: string): ValidationMsg => { msg: 'Invalid CA certificate, certificate must be in a valid PEM encoded X.509 format.', }; }; + +const validateInsecureSkipVerify = (value: string): ValidationMsg => { + // For a newly opened form where the field is not set yet, set the validation type to default. + if (value === undefined) { + return { type: 'default', msg: 'Migrate without validating a CA certificate' }; + } + + const valid = ['true', 'false', ''].includes(value); + + if (valid) { + return { type: 'success', msg: 'Migrate without validating a CA certificate' }; + } + + return { type: 'error', msg: 'Invalid Skip certificate validation value, must be true or false' }; +}; diff --git a/packages/forklift-console-plugin/src/modules/Providers/views/create/components/EsxiProviderCreateForm.tsx b/packages/forklift-console-plugin/src/modules/Providers/views/create/components/EsxiProviderCreateForm.tsx index e57a39970..4259691ac 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/views/create/components/EsxiProviderCreateForm.tsx +++ b/packages/forklift-console-plugin/src/modules/Providers/views/create/components/EsxiProviderCreateForm.tsx @@ -23,7 +23,7 @@ export const EsxiProviderCreateForm: React.FC = ({ const url = provider?.spec?.url; const vddkInitImage = provider?.spec?.settings?.['vddkInitImage']; - const sdkEndpoint = provider?.spec?.settings?.['sdkEndpoint'] || ''; + const sdkEndpoint = provider?.spec?.settings?.['sdkEndpoint']; const vddkHelperTextPopover = ( diff --git a/packages/forklift-console-plugin/src/modules/Providers/views/create/components/OVAProviderCreateForm.tsx b/packages/forklift-console-plugin/src/modules/Providers/views/create/components/OVAProviderCreateForm.tsx index 42089a8d9..6792ba1e8 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/views/create/components/OVAProviderCreateForm.tsx +++ b/packages/forklift-console-plugin/src/modules/Providers/views/create/components/OVAProviderCreateForm.tsx @@ -16,12 +16,11 @@ export const OVAProviderCreateForm: React.FC = ({ }) => { const { t } = useForkliftTranslation(); + const url = provider?.spec?.url; + const initialState = { validation: { - url: { - type: 'default', - msg: 'The NFS shared directory containing the Open Virtual Appliance (OVA) files, for example: 10.10.0.10:/ova .', - }, + url: validateOvaNfsPath(url), }, }; @@ -44,7 +43,7 @@ export const OVAProviderCreateForm: React.FC = ({ const handleChange = useCallback( (id, value) => { - const trimmedValue = value.trim(); + const trimmedValue = value?.trim(); if (id === 'url') { const validationState = validateOvaNfsPath(trimmedValue); @@ -72,7 +71,7 @@ export const OVAProviderCreateForm: React.FC = ({ id="url" name="url" isRequired - value={provider?.spec?.url || ''} + value={url || ''} validated={state.validation.url.type} onChange={(value) => handleChange('url', value)} /> diff --git a/packages/forklift-console-plugin/src/modules/Providers/views/create/components/OpenshiftProviderCreateForm.tsx b/packages/forklift-console-plugin/src/modules/Providers/views/create/components/OpenshiftProviderCreateForm.tsx index 764c0d018..59ec44842 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/views/create/components/OpenshiftProviderCreateForm.tsx +++ b/packages/forklift-console-plugin/src/modules/Providers/views/create/components/OpenshiftProviderCreateForm.tsx @@ -16,14 +16,11 @@ export const OpenshiftProviderFormCreate: React.FC { const { t } = useForkliftTranslation(); - const url = provider?.spec?.url || ''; + const url = provider?.spec?.url; const initialState = { validation: { - url: { - type: 'default', - msg: 'The URL of the Openshift Virtualization API endpoint, for example: https://example.com:6443 .', - }, + url: validateOpenshiftURL(url), }, }; @@ -48,7 +45,7 @@ export const OpenshiftProviderFormCreate: React.FC { if (id !== 'url') return; - const trimmedUrl: string = value.toString().trim(); + const trimmedUrl: string = value?.toString().trim(); const validationState = validateOpenshiftURL(trimmedUrl); dispatch({ diff --git a/packages/forklift-console-plugin/src/modules/Providers/views/create/components/OpenstackProviderCreateForm.tsx b/packages/forklift-console-plugin/src/modules/Providers/views/create/components/OpenstackProviderCreateForm.tsx index ce702111a..56638b21f 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/views/create/components/OpenstackProviderCreateForm.tsx +++ b/packages/forklift-console-plugin/src/modules/Providers/views/create/components/OpenstackProviderCreateForm.tsx @@ -16,12 +16,11 @@ export const OpenstackProviderCreateForm: React.FC { const { t } = useForkliftTranslation(); + const url = provider?.spec?.url; + const initialState = { validation: { - url: { - type: 'default', - msg: 'The URL of the OpenStack Identity (Keystone) API endpoint, for example: https://identity_service.com:5000/v3 .', - }, + url: validateOpenstackURL(url), }, }; @@ -46,7 +45,7 @@ export const OpenstackProviderCreateForm: React.FC { if (id !== 'url') return; - const trimmedURL: string = value.trim(); + const trimmedURL: string = value?.trim(); const validationState = validateOpenstackURL(trimmedURL); dispatch({ @@ -74,7 +73,7 @@ export const OpenstackProviderCreateForm: React.FC handleChange('url', value)} /> diff --git a/packages/forklift-console-plugin/src/modules/Providers/views/create/components/OvirtProviderCreateForm.tsx b/packages/forklift-console-plugin/src/modules/Providers/views/create/components/OvirtProviderCreateForm.tsx index 141ec223b..9ac293e79 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/views/create/components/OvirtProviderCreateForm.tsx +++ b/packages/forklift-console-plugin/src/modules/Providers/views/create/components/OvirtProviderCreateForm.tsx @@ -16,12 +16,11 @@ export const OvirtProviderCreateForm: React.FC = ( }) => { const { t } = useForkliftTranslation(); + const url = provider?.spec?.url; + const initialState = { validation: { - url: { - type: 'default', - msg: 'The URL of the Red Hat Virtualization Manager (RHVM) API endpoint, for example: https://rhv-host-example.com/ovirt-engine/api .', - }, + url: validateOvirtURL(url), }, }; @@ -46,7 +45,7 @@ export const OvirtProviderCreateForm: React.FC = ( (id, value) => { if (id !== 'url') return; - const trimmedValue: string = value.trim(); + const trimmedValue: string = value?.trim(); const validationState = validateOvirtURL(trimmedValue); dispatch({ @@ -74,7 +73,7 @@ export const OvirtProviderCreateForm: React.FC = ( type="text" id="url" name="url" - value={provider?.spec?.url || ''} + value={url || ''} validated={state.validation.url.type} onChange={(value) => handleChange('url', value)} /> diff --git a/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/EsxiCredentialsEdit.tsx b/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/EsxiCredentialsEdit.tsx index f9448b485..b12f2a5bf 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/EsxiCredentialsEdit.tsx +++ b/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/EsxiCredentialsEdit.tsx @@ -25,8 +25,8 @@ export const EsxiCredentialsEdit: React.FC = ({ secret, onCh const user = safeBase64Decode(secret?.data?.user); const password = safeBase64Decode(secret?.data?.password); const url = safeBase64Decode(secret?.data?.url); - const cacert = safeBase64Decode(secret?.data?.cacert || ''); - const insecureSkipVerify = safeBase64Decode(secret?.data?.insecureSkipVerify || '') === 'true'; + const cacert = safeBase64Decode(secret?.data?.cacert); + const insecureSkipVerify = safeBase64Decode(secret?.data?.insecureSkipVerify); const insecureSkipVerifyHelperTextPopover = ( @@ -57,7 +57,7 @@ export const EsxiCredentialsEdit: React.FC = ({ secret, onCh validation: { user: esxiSecretFieldValidator('user', user), password: esxiSecretFieldValidator('password', password), - insecureSkipVerify: { type: 'default', msg: 'Skip certificate validation' }, + insecureSkipVerify: esxiSecretFieldValidator('insecureSkipVerify', insecureSkipVerify), cacert: esxiSecretFieldValidator('cacert', cacert), }, }; @@ -88,8 +88,8 @@ export const EsxiCredentialsEdit: React.FC = ({ secret, onCh // don't trim fields that allow spaces const encodedValue = ['cacert'].includes(id) - ? Base64.encode(value) - : Base64.encode(value.trim()); + ? Base64.encode(value || '') + : Base64.encode(value?.trim() || ''); onChange({ ...secret, data: { ...secret.data, [id]: encodedValue } }); }, @@ -174,7 +174,7 @@ export const EsxiCredentialsEdit: React.FC = ({ secret, onCh id="insecureSkipVerify" name="insecureSkipVerify" label={t('Skip certificate validation')} - isChecked={insecureSkipVerify} + isChecked={insecureSkipVerify === 'true'} hasCheckIcon onChange={(value) => handleChange('insecureSkipVerify', value ? 'true' : 'false')} /> @@ -210,7 +210,7 @@ export const EsxiCredentialsEdit: React.FC = ({ secret, onCh onDataChange={(value) => handleChange('cacert', value)} onTextChange={(value) => handleChange('cacert', value)} onClearClick={() => handleChange('cacert', '')} - isDisabled={insecureSkipVerify} + isDisabled={insecureSkipVerify === 'true'} /> diff --git a/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/OpenshiftCredentialsEdit.tsx b/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/OpenshiftCredentialsEdit.tsx index 80970a06f..abf5edeb5 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/OpenshiftCredentialsEdit.tsx +++ b/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/OpenshiftCredentialsEdit.tsx @@ -22,10 +22,10 @@ import { EditComponentProps } from '../BaseCredentialsSection'; export const OpenshiftCredentialsEdit: React.FC = ({ secret, onChange }) => { const { t } = useForkliftTranslation(); - const url = safeBase64Decode(secret?.data?.url || ''); - const token = safeBase64Decode(secret?.data?.token || ''); - const insecureSkipVerify = safeBase64Decode(secret?.data?.insecureSkipVerify || '') === 'true'; - const cacert = safeBase64Decode(secret?.data?.cacert || ''); + const url = safeBase64Decode(secret?.data?.url); + const token = safeBase64Decode(secret?.data?.token); + const insecureSkipVerify = safeBase64Decode(secret?.data?.insecureSkipVerify); + const cacert = safeBase64Decode(secret?.data?.cacert); const insecureSkipVerifyHelperTextPopover = ( @@ -54,15 +54,9 @@ export const OpenshiftCredentialsEdit: React.FC = ({ secret, const initialState = { passwordHidden: true, validation: { - token: { - type: 'default', - msg: 'A service account token, required for authenticating the the connection to the API server.', - }, - insecureSkipVerify: { type: 'default', msg: 'Migrate without validating a CA certificate' }, - cacert: { - type: 'default', - msg: 'The Manager CA certificate unless it was replaced by a third-party certificate, in which case, enter the Manager Apache CA certificate.', - }, + token: openshiftSecretFieldValidator('token', token), + insecureSkipVerify: openshiftSecretFieldValidator('insecureSkipVerify', insecureSkipVerify), + cacert: openshiftSecretFieldValidator('cacert', cacert), }, }; @@ -93,8 +87,8 @@ export const OpenshiftCredentialsEdit: React.FC = ({ secret, // don't trim fields that allow spaces const encodedValue = ['cacert'].includes(id) - ? Base64.encode(value) - : Base64.encode(value.trim()); + ? Base64.encode(value || '') + : Base64.encode(value?.trim() || ''); onChange({ ...secret, data: { ...secret.data, [id]: encodedValue } }); }, @@ -155,15 +149,14 @@ export const OpenshiftCredentialsEdit: React.FC = ({ secret, } fieldId="insecureSkipVerify" validated={state.validation.insecureSkipVerify.type} - helperText={state.validation.insecureSkipVerify.msg} helperTextInvalid={state.validation.insecureSkipVerify.msg} > handleChange('insecureSkipVerify', value ? 'true' : 'false')} /> @@ -202,7 +195,7 @@ export const OpenshiftCredentialsEdit: React.FC = ({ secret, onClearClick={() => handleChange('cacert', '')} browseButtonText="Upload" url={url} - isDisabled={insecureSkipVerify} + isDisabled={insecureSkipVerify === 'true'} /> diff --git a/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/OpenstackCredentialsEdit.tsx b/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/OpenstackCredentialsEdit.tsx index 78dff3269..bdb41f1aa 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/OpenstackCredentialsEdit.tsx +++ b/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/OpenstackCredentialsEdit.tsx @@ -34,11 +34,11 @@ export const OpenstackCredentialsEdit: React.FC = ({ secret, ); - const url = safeBase64Decode(secret?.data?.url || ''); - const authType = safeBase64Decode(secret?.data?.authType || ''); - const username = safeBase64Decode(secret?.data?.username || ''); - const insecureSkipVerify = safeBase64Decode(secret?.data?.insecureSkipVerify || '') === 'true'; - const cacert = safeBase64Decode(secret?.data?.cacert || ''); + const url = safeBase64Decode(secret?.data?.url); + const authType = safeBase64Decode(secret?.data?.authType); + const username = safeBase64Decode(secret?.data?.username); + const insecureSkipVerify = safeBase64Decode(secret?.data?.insecureSkipVerify); + const cacert = safeBase64Decode(secret?.data?.cacert); let authenticationType: | 'passwordSecretFields' @@ -74,11 +74,8 @@ export const OpenstackCredentialsEdit: React.FC = ({ secret, const initialState = { authenticationType: authenticationType, validation: { - cacert: { - type: 'default', - msg: 'The Manager CA certificate unless it was replaced by a third-party certificate, in which case, enter the Manager Apache CA certificate.', - }, - insecureSkipVerify: { type: 'default', msg: 'Migrate without validating a CA certificate' }, + cacert: openstackSecretFieldValidator('cacert', cacert), + insecureSkipVerify: openstackSecretFieldValidator('insecureSkipVerify', insecureSkipVerify), }, }; @@ -112,8 +109,8 @@ export const OpenstackCredentialsEdit: React.FC = ({ secret, // don't trim fields that allow spaces const encodedValue = ['cacert'].includes(id) - ? Base64.encode(value) - : Base64.encode(value.trim()); + ? Base64.encode(value || '') + : Base64.encode(value?.trim() || ''); onChange({ ...secret, data: { ...secret.data, [id]: encodedValue } }); }, @@ -139,8 +136,8 @@ export const OpenstackCredentialsEdit: React.FC = ({ secret, data: { ...secret.data, ['authType']: Base64.encode('token'), - userID: '', - username: '', + userID: undefined, + username: undefined, }, }); break; @@ -152,8 +149,8 @@ export const OpenstackCredentialsEdit: React.FC = ({ secret, data: { ...secret.data, ['authType']: Base64.encode('applicationcredential'), - applicationCredentialID: '', - username: '', + applicationCredentialID: undefined, + username: undefined, }, }); break; @@ -257,14 +254,14 @@ export const OpenstackCredentialsEdit: React.FC = ({ secret, label={insecureSkipVerifyHelperTextMsgs.successAndSkipped} labelOff={insecureSkipVerifyHelperTextMsgs.successAndNotSkipped} aria-label={insecureSkipVerifyHelperTextMsgs.successAndSkipped} - isChecked={insecureSkipVerify} + isChecked={insecureSkipVerify === 'true'} hasCheckIcon onChange={(value) => handleChange('insecureSkipVerify', value ? 'true' : 'false')} /> = ({ secret, onClearClick={() => handleChange('cacert', '')} browseButtonText="Upload" url={url} - isDisabled={insecureSkipVerify} + isDisabled={insecureSkipVerify === 'true'} /> diff --git a/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/OpenstackCredentialsEditFormGroups/ApplicationCredentialNameSecretFieldsFormGroup.tsx b/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/OpenstackCredentialsEditFormGroups/ApplicationCredentialNameSecretFieldsFormGroup.tsx index 1d0a7cfde..4162d292f 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/OpenstackCredentialsEditFormGroups/ApplicationCredentialNameSecretFieldsFormGroup.tsx +++ b/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/OpenstackCredentialsEditFormGroups/ApplicationCredentialNameSecretFieldsFormGroup.tsx @@ -15,36 +15,28 @@ export const ApplicationCredentialNameSecretFieldsFormGroup: React.FC { const { t } = useForkliftTranslation(); - const applicationCredentialName = safeBase64Decode(secret?.data?.applicationCredentialName || ''); - const applicationCredentialSecret = safeBase64Decode( - secret?.data?.applicationCredentialSecret || '', - ); - const username = safeBase64Decode(secret?.data?.username || ''); - const regionName = safeBase64Decode(secret?.data?.regionName || ''); - const projectName = safeBase64Decode(secret?.data?.projectName || ''); - const domainName = safeBase64Decode(secret?.data?.domainName || ''); + const applicationCredentialName = safeBase64Decode(secret?.data?.applicationCredentialName); + const applicationCredentialSecret = safeBase64Decode(secret?.data?.applicationCredentialSecret); + const username = safeBase64Decode(secret?.data?.username); + const regionName = safeBase64Decode(secret?.data?.regionName); + const projectName = safeBase64Decode(secret?.data?.projectName); + const domainName = safeBase64Decode(secret?.data?.domainName); const initialState = { passwordHidden: true, validation: { - applicationCredentialName: { - type: 'default', - msg: 'OpenStack application credential name needed for application credential authentication.', - }, - applicationCredentialSecret: { - type: 'default', - msg: 'OpenStack application credential Secret needed for the application credential authentication.', - }, - username: { - type: 'default', - msg: 'A username for connecting to the OpenStack Identity (Keystone) endpoint.', - }, - regionName: { type: 'default', msg: 'OpenStack region name.' }, - projectName: { - type: 'default', - msg: 'OpenStack application credential name needed for application credential authentication.', - }, - domainName: { type: 'default', msg: 'OpenStack domain name.' }, + applicationCredentialName: openstackSecretFieldValidator( + 'applicationCredentialName', + applicationCredentialName, + ), + applicationCredentialSecret: openstackSecretFieldValidator( + 'applicationCredentialSecret', + applicationCredentialSecret, + ), + username: openstackSecretFieldValidator('username', username), + regionName: openstackSecretFieldValidator('regionName', regionName), + projectName: openstackSecretFieldValidator('projectName', projectName), + domainName: openstackSecretFieldValidator('domainName', domainName), }, }; @@ -73,7 +65,7 @@ export const ApplicationCredentialNameSecretFieldsFormGroup: React.FC }) => { const { t } = useForkliftTranslation(); - const applicationCredentialID = safeBase64Decode(secret?.data?.applicationCredentialID || ''); - const applicationCredentialSecret = safeBase64Decode( - secret?.data?.applicationCredentialSecret || '', - ); - const regionName = safeBase64Decode(secret?.data?.regionName || ''); - const projectName = safeBase64Decode(secret?.data?.projectName || ''); + const applicationCredentialID = safeBase64Decode(secret?.data?.applicationCredentialID); + const applicationCredentialSecret = safeBase64Decode(secret?.data?.applicationCredentialSecret); + const regionName = safeBase64Decode(secret?.data?.regionName); + const projectName = safeBase64Decode(secret?.data?.projectName); const initialState = { passwordHidden: true, validation: { - applicationCredentialID: { - type: 'default', - msg: 'OpenStack application credential ID needed for the application credential authentication.', - }, - applicationCredentialSecret: { - type: 'default', - msg: 'OpenStack application credential Secret needed for the application credential authentication.', - }, - regionName: { type: 'default', msg: 'OpenStack region name.' }, - projectName: { type: 'default', msg: 'OpenStack project name.' }, + applicationCredentialID: openstackSecretFieldValidator( + 'applicationCredentialID', + applicationCredentialID, + ), + applicationCredentialSecret: openstackSecretFieldValidator( + 'applicationCredentialSecret', + applicationCredentialSecret, + ), + regionName: openstackSecretFieldValidator('regionName', regionName), + projectName: openstackSecretFieldValidator('projectName', projectName), }, }; @@ -63,7 +61,7 @@ export const ApplicationWithCredentialsIDFormGroup: React.FC const validationState = openstackSecretFieldValidator(id, value); dispatch({ type: 'SET_FIELD_VALIDATED', payload: { field: id, validationState } }); - const encodedValue = Base64.encode(value.trim()); + const encodedValue = Base64.encode(value?.trim() || ''); onChange({ ...secret, data: { ...secret.data, [id]: encodedValue } }); }, [secret, onChange], diff --git a/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/OpenstackCredentialsEditFormGroups/PasswordSecretFieldsFormGroup.tsx b/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/OpenstackCredentialsEditFormGroups/PasswordSecretFieldsFormGroup.tsx index c6d1a981d..a5a104b1e 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/OpenstackCredentialsEditFormGroups/PasswordSecretFieldsFormGroup.tsx +++ b/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/OpenstackCredentialsEditFormGroups/PasswordSecretFieldsFormGroup.tsx @@ -15,26 +15,20 @@ export const PasswordSecretFieldsFormGroup: React.FC = ({ }) => { const { t } = useForkliftTranslation(); - const username = safeBase64Decode(secret?.data?.username || ''); - const password = safeBase64Decode(secret?.data?.password || ''); - const regionName = safeBase64Decode(secret?.data?.regionName || ''); - const projectName = safeBase64Decode(secret?.data?.projectName || ''); - const domainName = safeBase64Decode(secret?.data?.domainName || ''); + const username = safeBase64Decode(secret?.data?.username); + const password = safeBase64Decode(secret?.data?.password); + const regionName = safeBase64Decode(secret?.data?.regionName); + const projectName = safeBase64Decode(secret?.data?.projectName); + const domainName = safeBase64Decode(secret?.data?.domainName); const initialState = { passwordHidden: true, validation: { - username: { - type: 'default', - msg: 'A username for connecting to the OpenStack Identity (Keystone) endpoint.', - }, - password: { - type: 'default', - msg: 'A user password for connecting to the OpenStack Identity (Keystone) endpoint.', - }, - regionName: { type: 'default', msg: 'OpenStack region name.' }, - projectName: { type: 'default', msg: 'OpenStack project name.' }, - domainName: { type: 'default', msg: 'OpenStack domain name.' }, + username: openstackSecretFieldValidator('username', username), + password: openstackSecretFieldValidator('password', password), + regionName: openstackSecretFieldValidator('regionName', regionName), + projectName: openstackSecretFieldValidator('projectName', projectName), + domainName: openstackSecretFieldValidator('domainName', domainName), }, }; @@ -63,7 +57,7 @@ export const PasswordSecretFieldsFormGroup: React.FC = ({ const validationState = openstackSecretFieldValidator(id, value); dispatch({ type: 'SET_FIELD_VALIDATED', payload: { field: id, validationState } }); - const encodedValue = Base64.encode(value.trim()); + const encodedValue = Base64.encode(value?.trim() || ''); onChange({ ...secret, data: { ...secret.data, [id]: encodedValue } }); }, [secret, onChange], diff --git a/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/OpenstackCredentialsEditFormGroups/TokenWithUserIDSecretFieldsFormGroup.tsx b/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/OpenstackCredentialsEditFormGroups/TokenWithUserIDSecretFieldsFormGroup.tsx index 413ef9baa..b834dc669 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/OpenstackCredentialsEditFormGroups/TokenWithUserIDSecretFieldsFormGroup.tsx +++ b/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/OpenstackCredentialsEditFormGroups/TokenWithUserIDSecretFieldsFormGroup.tsx @@ -15,21 +15,18 @@ export const TokenWithUserIDSecretFieldsFormGroup: React.FC }) => { const { t } = useForkliftTranslation(); - const token = safeBase64Decode(secret?.data?.token || ''); - const userID = safeBase64Decode(secret?.data?.userID || ''); - const projectID = safeBase64Decode(secret?.data?.projectID || ''); - const regionName = safeBase64Decode(secret?.data?.regionName || ''); + const token = safeBase64Decode(secret?.data?.token); + const userID = safeBase64Decode(secret?.data?.userID); + const projectID = safeBase64Decode(secret?.data?.projectID); + const regionName = safeBase64Decode(secret?.data?.regionName); const initialState = { passwordHidden: true, validation: { - token: { type: 'default', msg: 'OpenStack token for authentication using a user name.' }, - userID: { - type: 'default', - msg: 'A user ID for connecting to the OpenStack Identity (Keystone) endpoint.', - }, - projectID: { type: 'default', msg: 'OpenStack project ID.' }, - regionName: { type: 'default', msg: 'OpenStack region name.' }, + token: openstackSecretFieldValidator('token', token), + userID: openstackSecretFieldValidator('userID', userID), + projectID: openstackSecretFieldValidator('projectID', projectID), + regionName: openstackSecretFieldValidator('regionName', regionName), }, }; @@ -57,7 +54,7 @@ export const TokenWithUserIDSecretFieldsFormGroup: React.FC const validationState = openstackSecretFieldValidator(id, value); dispatch({ type: 'SET_FIELD_VALIDATED', payload: { field: id, validationState } }); - const encodedValue = Base64.encode(value.trim()); + const encodedValue = Base64.encode(value?.trim() || ''); onChange({ ...secret, data: { ...secret.data, [id]: encodedValue } }); }, [secret, onChange], diff --git a/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/OpenstackCredentialsEditFormGroups/TokenWithUsernameSecretFieldsFormGroup.tsx b/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/OpenstackCredentialsEditFormGroups/TokenWithUsernameSecretFieldsFormGroup.tsx index 248c6e0a1..f4d53cfc5 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/OpenstackCredentialsEditFormGroups/TokenWithUsernameSecretFieldsFormGroup.tsx +++ b/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/OpenstackCredentialsEditFormGroups/TokenWithUsernameSecretFieldsFormGroup.tsx @@ -15,23 +15,20 @@ export const TokenWithUsernameSecretFieldsFormGroup: React.FC { const { t } = useForkliftTranslation(); - const token = safeBase64Decode(secret?.data?.token || ''); - const username = safeBase64Decode(secret?.data?.username || ''); - const regionName = safeBase64Decode(secret?.data?.regionName || ''); - const projectName = safeBase64Decode(secret?.data?.projectName || ''); - const domainName = safeBase64Decode(secret?.data?.domainName || ''); + const token = safeBase64Decode(secret?.data?.token); + const username = safeBase64Decode(secret?.data?.username); + const regionName = safeBase64Decode(secret?.data?.regionName); + const projectName = safeBase64Decode(secret?.data?.projectName); + const domainName = safeBase64Decode(secret?.data?.domainName); const initialState = { passwordHidden: true, validation: { - token: { type: 'default', msg: 'OpenStack token for authentication using a user name.' }, - username: { - type: 'default', - msg: 'A username for connecting to the OpenStack Identity (Keystone) endpoint.', - }, - regionName: { type: 'default', msg: 'OpenStack region name.' }, - projectName: { type: 'default', msg: 'OpenStack project name.' }, - domainName: { type: 'default', msg: 'OpenStack domain name.' }, + token: openstackSecretFieldValidator('token', token), + username: openstackSecretFieldValidator('username', username), + regionName: openstackSecretFieldValidator('regionName', regionName), + projectName: openstackSecretFieldValidator('projectName', projectName), + domainName: openstackSecretFieldValidator('domainName', domainName), }, }; @@ -59,7 +56,7 @@ export const TokenWithUsernameSecretFieldsFormGroup: React.FC = ({ secret, onChange }) => { const { t } = useForkliftTranslation(); - const user = safeBase64Decode(secret?.data?.user || ''); - const url = safeBase64Decode(secret?.data?.url || ''); - const password = safeBase64Decode(secret?.data?.password || ''); - const insecureSkipVerify = safeBase64Decode(secret?.data?.insecureSkipVerify || '') === 'true'; - const cacert = safeBase64Decode(secret?.data?.cacert || ''); + const url = safeBase64Decode(secret?.data?.url); + const user = safeBase64Decode(secret?.data?.user); + const password = safeBase64Decode(secret?.data?.password); + const insecureSkipVerify = safeBase64Decode(secret?.data?.insecureSkipVerify); + const cacert = safeBase64Decode(secret?.data?.cacert); const insecureSkipVerifyHelperTextPopover = ( @@ -57,19 +57,10 @@ export const OvirtCredentialsEdit: React.FC = ({ secret, onC const initialState = { passwordHidden: true, validation: { - user: { - type: 'default', - msg: 'A username for connecting to the Red Hat Virtualization Manager (RHVM) API endpoint, for example: name@internal .', - }, - password: { - type: 'default', - msg: 'A user password for connecting to the Red Hat Virtualization Manager (RHVM) API endpoint.', - }, - insecureSkipVerify: { type: 'default', msg: 'Skip certificate validation' }, - cacert: { - type: 'default', - msg: 'The Manager CA certificate unless it was replaced by a third-party certificate, in which case, enter the Manager Apache CA certificate.', - }, + user: ovirtSecretFieldValidator('user', user), + password: ovirtSecretFieldValidator('password', password), + insecureSkipVerify: ovirtSecretFieldValidator('insecureSkipVerify', insecureSkipVerify), + cacert: ovirtSecretFieldValidator('cacert', cacert), }, }; @@ -103,8 +94,8 @@ export const OvirtCredentialsEdit: React.FC = ({ secret, onC // don't trim fields that allow spaces const encodedValue = ['cacert'].includes(id) - ? Base64.encode(value) - : Base64.encode(value.trim()); + ? Base64.encode(value || '') + : Base64.encode(value?.trim() || ''); onChange({ ...secret, data: { ...secret.data, [id]: encodedValue } }); }, @@ -131,7 +122,7 @@ export const OvirtCredentialsEdit: React.FC = ({ secret, onC id="user" name="user" value={user} - validated={state.validation.user} + validated={state.validation.user.type} onChange={(value) => handleChange('user', value)} /> @@ -189,7 +180,7 @@ export const OvirtCredentialsEdit: React.FC = ({ secret, onC id="insecureSkipVerify" name="insecureSkipVerify" label={t('Skip certificate validation')} - isChecked={insecureSkipVerify} + isChecked={insecureSkipVerify === 'true'} hasCheckIcon onChange={(value) => handleChange('insecureSkipVerify', value ? 'true' : 'false')} /> @@ -228,7 +219,7 @@ export const OvirtCredentialsEdit: React.FC = ({ secret, onC onClearClick={() => handleChange('cacert', '')} browseButtonText="Upload" url={url} - isDisabled={insecureSkipVerify} + isDisabled={insecureSkipVerify === 'true'} /> diff --git a/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/VCenterCredentialsEdit.tsx b/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/VCenterCredentialsEdit.tsx index 3c6ddb583..788ec3eff 100644 --- a/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/VCenterCredentialsEdit.tsx +++ b/packages/forklift-console-plugin/src/modules/Providers/views/details/components/CredentialsSection/components/edit/VCenterCredentialsEdit.tsx @@ -25,8 +25,8 @@ export const VCenterCredentialsEdit: React.FC = ({ secret, o const user = safeBase64Decode(secret?.data?.user); const password = safeBase64Decode(secret?.data?.password); const url = safeBase64Decode(secret?.data?.url); - const cacert = safeBase64Decode(secret?.data?.cacert || ''); - const insecureSkipVerify = safeBase64Decode(secret?.data?.insecureSkipVerify || '') === 'true'; + const cacert = safeBase64Decode(secret?.data?.cacert); + const insecureSkipVerify = safeBase64Decode(secret?.data?.insecureSkipVerify); const insecureSkipVerifyHelperTextPopover = ( @@ -57,7 +57,7 @@ export const VCenterCredentialsEdit: React.FC = ({ secret, o validation: { user: vcenterSecretFieldValidator('user', user), password: vcenterSecretFieldValidator('password', password), - insecureSkipVerify: { type: 'default', msg: 'Skip certificate validation' }, + insecureSkipVerify: vcenterSecretFieldValidator('insecureSkipVerify', insecureSkipVerify), cacert: vcenterSecretFieldValidator('cacert', cacert), }, }; @@ -88,8 +88,8 @@ export const VCenterCredentialsEdit: React.FC = ({ secret, o // don't trim fields that allow spaces const encodedValue = ['cacert'].includes(id) - ? Base64.encode(value) - : Base64.encode(value.trim()); + ? Base64.encode(value || '') + : Base64.encode(value?.trim() || ''); onChange({ ...secret, data: { ...secret.data, [id]: encodedValue } }); }, @@ -174,7 +174,7 @@ export const VCenterCredentialsEdit: React.FC = ({ secret, o id="insecureSkipVerify" name="insecureSkipVerify" label={t('Skip certificate validation')} - isChecked={insecureSkipVerify} + isChecked={insecureSkipVerify === 'true'} hasCheckIcon onChange={(value) => handleChange('insecureSkipVerify', value ? 'true' : 'false')} /> @@ -210,7 +210,7 @@ export const VCenterCredentialsEdit: React.FC = ({ secret, o onDataChange={(value) => handleChange('cacert', value)} onTextChange={(value) => handleChange('cacert', value)} onClearClick={() => handleChange('cacert', '')} - isDisabled={insecureSkipVerify} + isDisabled={insecureSkipVerify === 'true'} />