From 2fde3c750eb6c6345c5fcf4bcbedfd4087d6143f Mon Sep 17 00:00:00 2001 From: Montse Ortega Date: Fri, 22 Mar 2024 09:05:16 +0100 Subject: [PATCH] MGMT-15999: Assisted Installer UI should allow patch manifests (#2530) * Allow to use patch manifests to install cluster * Adjusting tests * Add file size validation for patch files --- libs/types/assisted-installer-service.d.ts | 60 ++++++++++++++++--- ...2-modifying-existing-custom-manifest.cy.ts | 10 +++- libs/ui-lib/lib/common/utils.ts | 5 +- .../customManifestsValidationSchema.tsx | 17 ++++-- 4 files changed, 76 insertions(+), 16 deletions(-) diff --git a/libs/types/assisted-installer-service.d.ts b/libs/types/assisted-installer-service.d.ts index 8710fa57af..5ccfc5ebaf 100644 --- a/libs/types/assisted-installer-service.d.ts +++ b/libs/types/assisted-installer-service.d.ts @@ -363,6 +363,10 @@ export interface Cluster { */ tags?: string; 'last-installation-preparation'?: LastInstallationPreparation; + /** + * Indication if organization soft timeouts is enabled for the cluster. + */ + orgSoftTimeoutsEnabled?: boolean; } export interface ClusterCreateParams { /** @@ -581,8 +585,7 @@ export interface ClusterProgressInfo { finalizingStagePercentage?: number; finalizingStage?: FinalizingStage; finalizingStageStartedAt?: string; // date-time - nodeUpdaterStartedAt?: string; // date-time - nodeUpdaterFinishedAt?: string; // date-time + finalizingStageTimedOut?: boolean; } export type ClusterValidationId = | 'machine-cidr-defined' @@ -987,11 +990,10 @@ export type FeatureSupportLevelId = * Cluster finalizing stage managed by controller */ export type FinalizingStage = - | 'Waiting for finalizing' | 'Waiting for cluster operators' | 'Adding router ca' - | 'Waiting for olm operators' - | 'Applying manifests' + | 'Applying olm manifests' + | 'Waiting for olm operators csv initialization' | 'Waiting for olm operators csv' | 'Done'; export type FreeAddressesList = string /* ipv4 */[]; @@ -1140,6 +1142,10 @@ export interface Host { * The last time the host's agent communicated with the service. */ checkedInAt?: string; // date-time + /** + * Indicate that connection to assisted service was timed out when soft timeout is enabled. + */ + connectionTimedOut?: boolean; /** * The last time the host's agent tried to register in the service. */ @@ -1343,6 +1349,10 @@ export interface HostRegistrationResponse { * The last time the host's agent communicated with the service. */ checkedInAt?: string; // date-time + /** + * Indicate that connection to assisted service was timed out when soft timeout is enabled. + */ + connectionTimedOut?: boolean; /** * The last time the host's agent tried to register in the service. */ @@ -1466,6 +1476,10 @@ export interface HostUpdateParams { * A string which will be used as Authorization Bearer token to fetch the ignition from ignitionEndpointUrl. */ ignitionEndpointToken?: string; + /** + * JSON-formatted string of additional HTTP headers when fetching the ignition. + */ + ignitionEndpointHttpHeaders?: IgnitionEndpointHttpHeadersParams[]; /** * Labels to be added to the corresponding node. */ @@ -1526,6 +1540,16 @@ export interface IgnitionEndpoint { */ caCertificate?: string; } +export interface IgnitionEndpointHttpHeadersParams { + /** + * The key for the http header's key-value pair. + */ + key: string; + /** + * The value for the http header's key-value pair. + */ + value: string; +} export interface IgnoredValidations { /** * JSON-formatted list of cluster validation IDs that will be ignored for all hosts that belong to this cluster. It may also contain a list with a single string "all" to ignore all cluster validations. Some validations cannot be ignored. @@ -2111,7 +2135,7 @@ export interface OpenshiftVersion { /** * Level of support of the version. */ - supportLevel: 'beta' | 'production' | 'maintenance'; + supportLevel: 'beta' | 'production' | 'maintenance' | 'end-of-life'; /** * Indication that the version is the recommended one. */ @@ -2292,6 +2316,10 @@ export interface RebootForReclaimRequest { */ hostFsMountDir: string; } +/** + * Release channel. + */ +export type ReleaseChannel = 'candidate' | 'fast' | 'stable' | 'eus'; export interface ReleaseImage { /** * Version of the OpenShift cluster. @@ -2320,9 +2348,20 @@ export interface ReleaseImage { /** * Level of support of the version. */ - supportLevel?: 'beta' | 'production' | 'maintenance'; + supportLevel?: 'beta' | 'production' | 'maintenance' | 'end-of-life'; } export type ReleaseImages = ReleaseImage[]; +export interface ReleaseSource { + /** + * Version of the OpenShift cluster. + * example: + * 4.14 + */ + openshiftVersion: string; + multiCpuArchitectures: ('x86_64' | 'aarch64' | 'arm64' | 'ppc64le' | 's390x')[]; + upgradeChannels: UpgradeChannel[]; +} +export type ReleaseSources = ReleaseSource[]; export interface Route { /** * Interface to which packets for this route will be sent @@ -2497,6 +2536,13 @@ export interface UpgradeAgentResponse { * Agent upgrade result. */ export type UpgradeAgentResult = 'success' | 'failure'; +export interface UpgradeChannel { + /** + * The CPU architecture of the image. + */ + cpuArchitecture: 'x86_64' | 'aarch64' | 'arm64' | 'ppc64le' | 's390x' | 'multi'; + channels: ReleaseChannel[]; +} export interface Usage { /** * Unique idenftifier of the feature diff --git a/libs/ui-lib-tests/cypress/integration/custom-manifests/2-modifying-existing-custom-manifest.cy.ts b/libs/ui-lib-tests/cypress/integration/custom-manifests/2-modifying-existing-custom-manifest.cy.ts index b6d5127ba8..8719837aa4 100644 --- a/libs/ui-lib-tests/cypress/integration/custom-manifests/2-modifying-existing-custom-manifest.cy.ts +++ b/libs/ui-lib-tests/cypress/integration/custom-manifests/2-modifying-existing-custom-manifest.cy.ts @@ -88,7 +88,10 @@ describe(`Assisted Installer Custom manifests step`, () => { .attachFile(`custom-manifests/files/img.png`); CustomManifestsForm.expandedManifest(0) .fileUploadError() - .should('contain.text', 'File type is not supported. File type must be yaml, yml or json.'); + .should( + 'contain.text', + 'File type is not supported. File type must be yaml, yml ,json , yaml.patch. or yml.patch.', + ); commonActions.verifyNextIsDisabled(); }); @@ -97,7 +100,10 @@ describe(`Assisted Installer Custom manifests step`, () => { CustomManifestsForm.expandedManifest(0).fileName().clear().type('test.txt'); CustomManifestsForm.expandedManifest(0) .fileNameError() - .should('contain.text', 'Must have a yaml, yml or json extension and can not contain /.'); + .should( + 'contain.text', + 'Must have a yaml, yml, json, yaml.patch or yml.patch extension and can not contain /.', + ); CustomManifestsForm.validationAlert().should( 'contain.text', diff --git a/libs/ui-lib/lib/common/utils.ts b/libs/ui-lib/lib/common/utils.ts index 407d309448..8431c62a7e 100644 --- a/libs/ui-lib/lib/common/utils.ts +++ b/libs/ui-lib/lib/common/utils.ts @@ -4,10 +4,11 @@ import isString from 'lodash-es/isString.js'; import { loadAll } from 'js-yaml'; import { MAX_FILE_SIZE_BYTES, MAX_FILE_SIZE_OFFSET_FACTOR } from './configurations'; -export const FILENAME_REGEX = /^[^\/]*\.(yaml|yml|json)$/; +export const FILENAME_REGEX = /^[^/]*\.(yaml|yml|json|yaml.patch.*|yml.patch.*)$/; + export const FILE_TYPE_MESSAGE = 'Unsupported file type. Please provide a valid YAML file.'; export const INCORRECT_TYPE_FILE_MESSAGE = - 'File type is not supported. File type must be yaml, yml or json.'; + 'File type is not supported. File type must be yaml, yml ,json , yaml.patch. or yml.patch.'; export const getErrorMessage = (error: unknown): string => { if (error instanceof Error) { diff --git a/libs/ui-lib/lib/ocm/components/clusterConfiguration/manifestsConfiguration/components/customManifestsValidationSchema.tsx b/libs/ui-lib/lib/ocm/components/clusterConfiguration/manifestsConfiguration/components/customManifestsValidationSchema.tsx index ace75af9b5..59652fb842 100644 --- a/libs/ui-lib/lib/ocm/components/clusterConfiguration/manifestsConfiguration/components/customManifestsValidationSchema.tsx +++ b/libs/ui-lib/lib/ocm/components/clusterConfiguration/manifestsConfiguration/components/customManifestsValidationSchema.tsx @@ -7,7 +7,8 @@ import { validateFileType, INCORRECT_TYPE_FILE_MESSAGE, } from '../../../../../common/utils'; -const INCORRECT_FILENAME = 'Must have a yaml, yml or json extension and can not contain /.'; +const INCORRECT_FILENAME = + 'Must have a yaml, yml, json, yaml.patch or yml.patch extension and can not contain /.'; const UNIQUE_FOLDER_FILENAME = 'Ensure unique file names to avoid conflicts and errors.'; @@ -39,10 +40,16 @@ export const getFormViewManifestsValidationSchema = Yup.object return validateFileName(value); }) .concat(getUniqueValidationSchema), - manifestYaml: Yup.string() - .required('Required') - .test('not-big-file', getMaxFileSizeMessage, validateFileSize) - .test('not-valid-file', INCORRECT_TYPE_FILE_MESSAGE, validateFileType), + manifestYaml: Yup.string().when('filename', { + is: (filename: string) => !filename.includes('patch'), + then: Yup.string() + .required('Required') + .test('not-big-file', getMaxFileSizeMessage, validateFileSize) + .test('not-valid-file', INCORRECT_TYPE_FILE_MESSAGE, validateFileType), + otherwise: Yup.string() + .required('Required') + .test('not-big-file', getMaxFileSizeMessage, validateFileSize), // Validation of file content is not required if filename contains 'patch' + }), }), ), });