diff --git a/packages/dashboard-frontend/src/containers/Loader/Factory/Steps/Apply/Devfile/__tests__/prepareDevfile.spec.ts b/packages/dashboard-frontend/src/containers/Loader/Factory/Steps/Apply/Devfile/__tests__/prepareDevfile.spec.ts index 3d82fe0e5..1abb49956 100644 --- a/packages/dashboard-frontend/src/containers/Loader/Factory/Steps/Apply/Devfile/__tests__/prepareDevfile.spec.ts +++ b/packages/dashboard-frontend/src/containers/Loader/Factory/Steps/Apply/Devfile/__tests__/prepareDevfile.spec.ts @@ -27,6 +27,7 @@ describe('FactoryLoaderContainer/prepareDevfile', () => { describe('DEVWORKSPACE_METADATA_ANNOTATION attribute', () => { test('add the attribute with annotation', () => { const devfile = { + schemaVersion: '2.1.0', metadata: { generateName: 'wksp-', }, @@ -42,7 +43,7 @@ describe('FactoryLoaderContainer/prepareDevfile', () => { const newDevfile = prepareDevfile(devfile, factoryId, undefined, false); - expect(newDevfile.metadata.attributes).toEqual({ + expect(newDevfile.attributes).toEqual({ [DEVWORKSPACE_METADATA_ANNOTATION]: factorySource, }); }); @@ -65,18 +66,18 @@ describe('FactoryLoaderContainer/prepareDevfile', () => { metadata: { name: 'asdf', generateName: 'wksp-', - attributes: { - [DEVWORKSPACE_METADATA_ANNOTATION]: customAnnotation, - }, + }, + attributes: { + [DEVWORKSPACE_METADATA_ANNOTATION]: customAnnotation, }, } as devfileApi.Devfile; const newDevfile = prepareDevfile(devfile, factoryId, undefined, false); - expect(newDevfile.metadata.attributes?.[DEVWORKSPACE_METADATA_ANNOTATION]).toEqual( + expect(newDevfile.attributes?.[DEVWORKSPACE_METADATA_ANNOTATION]).toEqual( expect.objectContaining(customAnnotation), ); - expect(newDevfile.metadata.attributes?.[DEVWORKSPACE_METADATA_ANNOTATION]).toEqual( + expect(newDevfile.attributes?.[DEVWORKSPACE_METADATA_ANNOTATION]).toEqual( expect.objectContaining(factorySource), ); }); @@ -94,6 +95,7 @@ describe('FactoryLoaderContainer/prepareDevfile', () => { const badMetadataAnnotation = 'bad-metadata-annotation'; const devfile = { + schemaVersion: '2.1.0', metadata: { generateName: 'wksp-', attributes: { @@ -104,12 +106,10 @@ describe('FactoryLoaderContainer/prepareDevfile', () => { const newDevfile = prepareDevfile(devfile, factoryId, undefined, false); - expect(newDevfile.metadata.attributes?.[DEVWORKSPACE_METADATA_ANNOTATION]).not.toContain( + expect(newDevfile.attributes?.[DEVWORKSPACE_METADATA_ANNOTATION]).not.toContain( badMetadataAnnotation, ); - expect(newDevfile.metadata.attributes?.[DEVWORKSPACE_METADATA_ANNOTATION]).toEqual( - factorySource, - ); + expect(newDevfile.attributes?.[DEVWORKSPACE_METADATA_ANNOTATION]).toEqual(factorySource); }); test('update the attribute with annotation - bad DEVWORKSPACE_DEVFILE_SOURCE', () => { @@ -127,6 +127,7 @@ describe('FactoryLoaderContainer/prepareDevfile', () => { }; const devfile = { + schemaVersion: '2.1.0', metadata: { generateName: 'wksp-', attributes: { @@ -137,12 +138,10 @@ describe('FactoryLoaderContainer/prepareDevfile', () => { const newDevfile = prepareDevfile(devfile, factoryId, undefined, false); - expect(newDevfile.metadata.attributes?.[DEVWORKSPACE_METADATA_ANNOTATION]).not.toContain( + expect(newDevfile.attributes?.[DEVWORKSPACE_METADATA_ANNOTATION]).not.toContain( expect.objectContaining(badDevworkspaceDevfileSource), ); - expect(newDevfile.metadata.attributes?.[DEVWORKSPACE_METADATA_ANNOTATION]).toEqual( - factorySource, - ); + expect(newDevfile.attributes?.[DEVWORKSPACE_METADATA_ANNOTATION]).toEqual(factorySource); }); }); @@ -150,6 +149,7 @@ describe('FactoryLoaderContainer/prepareDevfile', () => { it('should not change the name', () => { const factoryId = 'url=https://devfile-location'; const devfile = { + schemaVersion: '2.1.0', metadata: { name: 'wksp-test', }, @@ -163,6 +163,7 @@ describe('FactoryLoaderContainer/prepareDevfile', () => { it('should append a suffix to the name', () => { const factoryId = 'url=https://devfile-location'; const devfile = { + schemaVersion: '2.1.0', metadata: { name: 'wksp-test', }, @@ -176,6 +177,7 @@ describe('FactoryLoaderContainer/prepareDevfile', () => { it('should generate a new name #1', () => { const factoryId = 'url=https://devfile-location'; const devfile = { + schemaVersion: '2.1.0', metadata: { generateName: 'wksp-', }, @@ -189,6 +191,7 @@ describe('FactoryLoaderContainer/prepareDevfile', () => { it('should generate a new name #2', () => { const factoryId = 'url=https://devfile-location'; const devfile = { + schemaVersion: '2.1.0', metadata: { generateName: 'wksp-', }, diff --git a/packages/dashboard-frontend/src/containers/Loader/Factory/Steps/Apply/Devfile/prepareDevfile.ts b/packages/dashboard-frontend/src/containers/Loader/Factory/Steps/Apply/Devfile/prepareDevfile.ts index 984d4b4e9..e2280810b 100644 --- a/packages/dashboard-frontend/src/containers/Loader/Factory/Steps/Apply/Devfile/prepareDevfile.ts +++ b/packages/dashboard-frontend/src/containers/Loader/Factory/Steps/Apply/Devfile/prepareDevfile.ts @@ -20,6 +20,7 @@ import { DEVWORKSPACE_DEVFILE_SOURCE, DEVWORKSPACE_METADATA_ANNOTATION, } from '../../../../../../services/workspace-client/devworkspace/devWorkspaceClient'; +import { getAttributesFromDevfileV2 } from '../../../../../../services/devfile/helper'; export type FactorySource = { factory?: { params: string } }; @@ -30,26 +31,21 @@ export function prepareDevfile( appendSuffix: boolean, ): devfileApi.Devfile { const devfile = cloneDeep(_devfile); - - // set factory ID - if (!devfile.metadata.attributes) { - devfile.metadata.attributes = {}; - } + const attributes = getAttributesFromDevfileV2(devfile); if ( - !devfile.metadata.attributes[DEVWORKSPACE_METADATA_ANNOTATION] || - typeof devfile.metadata.attributes[DEVWORKSPACE_METADATA_ANNOTATION] !== 'object' + !attributes[DEVWORKSPACE_METADATA_ANNOTATION] || + typeof attributes[DEVWORKSPACE_METADATA_ANNOTATION] !== 'object' ) { - devfile.metadata.attributes[DEVWORKSPACE_METADATA_ANNOTATION] = {}; + attributes[DEVWORKSPACE_METADATA_ANNOTATION] = {}; } - const dwMetadataAnnotations = devfile.metadata.attributes[DEVWORKSPACE_METADATA_ANNOTATION]; + const dwMetadataAnnotations = attributes[DEVWORKSPACE_METADATA_ANNOTATION]; const devfileSourceYaml = dwMetadataAnnotations[DEVWORKSPACE_DEVFILE_SOURCE]; let devfileSource = devfileSourceYaml ? load(devfileSourceYaml) : {}; if (typeof devfileSource !== 'object') { devfileSource = {}; } (devfileSource as FactorySource).factory = { params: factoryId }; - devfile.metadata.attributes[DEVWORKSPACE_METADATA_ANNOTATION][DEVWORKSPACE_DEVFILE_SOURCE] = - dump(devfileSource); + attributes[DEVWORKSPACE_METADATA_ANNOTATION][DEVWORKSPACE_DEVFILE_SOURCE] = dump(devfileSource); // update `metadata.name` in accordance to the policy if (devfile.metadata.generateName) { @@ -63,15 +59,7 @@ export function prepareDevfile( // propagate storage type if (storageType === 'ephemeral') { - if (devfile.schemaVersion === '2.0.0') { - devfile.metadata.attributes[DEVWORKSPACE_STORAGE_TYPE_ATTR] = 'ephemeral'; - } else { - // for devfiles version 2.1.0 and above - if (!devfile.attributes) { - devfile.attributes = {}; - } - devfile.attributes[DEVWORKSPACE_STORAGE_TYPE_ATTR] = 'ephemeral'; - } + attributes[DEVWORKSPACE_STORAGE_TYPE_ATTR] = 'ephemeral'; } return devfile; diff --git a/packages/dashboard-frontend/src/services/devfile/adapter.ts b/packages/dashboard-frontend/src/services/devfile/adapter.ts index da5c85fae..31a2b29e7 100644 --- a/packages/dashboard-frontend/src/services/devfile/adapter.ts +++ b/packages/dashboard-frontend/src/services/devfile/adapter.ts @@ -13,6 +13,7 @@ import devfileApi, { isDevfileV2 } from '../devfileApi'; import { DEVWORKSPACE_STORAGE_TYPE_ATTR } from '../devfileApi/devWorkspace/spec/template'; import { attributesToType } from '../storageTypes'; +import { getAttributesFromDevfileV2 } from './helper'; export type Devfile = che.WorkspaceDevfile | devfileApi.Devfile; @@ -29,30 +30,18 @@ export class DevfileAdapter { set storageType(type: che.WorkspaceStorageType) { if (isDevfileV2(this._devfile)) { + const attributes = getAttributesFromDevfileV2(this._devfile); if (type && type !== 'persistent') { - if (this._devfile.schemaVersion === '2.0.0') { - if (!this._devfile.metadata.attributes) { - this._devfile.metadata.attributes = {}; - } - this._devfile.metadata.attributes[DEVWORKSPACE_STORAGE_TYPE_ATTR] = type; - } else { - // for devfiles version 2.1.0 and above - if (!this._devfile.attributes) { - this._devfile.attributes = {}; - } - this._devfile.attributes[DEVWORKSPACE_STORAGE_TYPE_ATTR] = type; - } + attributes[DEVWORKSPACE_STORAGE_TYPE_ATTR] = type; } else { - if (this._devfile.metadata.attributes?.[DEVWORKSPACE_STORAGE_TYPE_ATTR]) { - delete this._devfile.metadata.attributes[DEVWORKSPACE_STORAGE_TYPE_ATTR]; - if (Object.keys(this._devfile.metadata.attributes).length === 0) { - delete this._devfile.metadata.attributes; - } + if (attributes[DEVWORKSPACE_STORAGE_TYPE_ATTR]) { + delete attributes[DEVWORKSPACE_STORAGE_TYPE_ATTR]; } - if (this._devfile.attributes?.[DEVWORKSPACE_STORAGE_TYPE_ATTR]) { - delete this._devfile.attributes[DEVWORKSPACE_STORAGE_TYPE_ATTR]; - if (Object.keys(this._devfile.attributes).length === 0) { + if (Object.keys(attributes).length === 0) { + if (this._devfile.attributes === attributes) { delete this._devfile.attributes; + } else if (this._devfile.metadata.attributes === attributes) { + delete this._devfile.metadata.attributes; } } } diff --git a/packages/dashboard-frontend/src/services/devfile/helper.ts b/packages/dashboard-frontend/src/services/devfile/helper.ts new file mode 100644 index 000000000..c4c57be61 --- /dev/null +++ b/packages/dashboard-frontend/src/services/devfile/helper.ts @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2018-2023 Red Hat, Inc. + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Red Hat, Inc. - initial API and implementation + */ + +import devfileApi from '../devfileApi'; + +export function getAttributesFromDevfileV2(devfile: devfileApi.Devfile) { + let attributes = {}; + if (devfile.schemaVersion?.startsWith('2.0')) { + if (!devfile.metadata.attributes) { + devfile.metadata.attributes = attributes; + } else { + attributes = devfile.metadata.attributes; + } + } else { + if (!devfile.attributes) { + devfile.attributes = attributes; + } else { + attributes = devfile.attributes; + } + } + + return attributes; +} diff --git a/packages/dashboard-frontend/src/store/FactoryResolver/normalizeDevfileV2.ts b/packages/dashboard-frontend/src/store/FactoryResolver/normalizeDevfileV2.ts index 9171afd46..694f6ac75 100644 --- a/packages/dashboard-frontend/src/store/FactoryResolver/normalizeDevfileV2.ts +++ b/packages/dashboard-frontend/src/store/FactoryResolver/normalizeDevfileV2.ts @@ -22,6 +22,7 @@ import { } from '../../services/workspace-client/devworkspace/devWorkspaceClient'; import { generateWorkspaceName } from '../../services/helpers/generateName'; import { FactoryParams } from '../../containers/Loader/buildFactoryParams'; +import { getAttributesFromDevfileV2 } from '../../services/devfile/helper'; /** * Returns a devfile from the FactoryResolver object. @@ -110,14 +111,13 @@ export default function normalizeDevfileV2( } else if (location) { devfileSource = dump({ url: { location } }); } - if (!devfile.metadata.attributes) { - devfile.metadata.attributes = {}; - } - if (!devfile.metadata.attributes[DEVWORKSPACE_METADATA_ANNOTATION]) { - devfile.metadata.attributes[DEVWORKSPACE_METADATA_ANNOTATION] = {}; + + const attributes = getAttributesFromDevfileV2(devfile); + + if (!attributes[DEVWORKSPACE_METADATA_ANNOTATION]) { + attributes[DEVWORKSPACE_METADATA_ANNOTATION] = {}; } - devfile.metadata.attributes[DEVWORKSPACE_METADATA_ANNOTATION][DEVWORKSPACE_DEVFILE_SOURCE] = - devfileSource; + attributes[DEVWORKSPACE_METADATA_ANNOTATION][DEVWORKSPACE_DEVFILE_SOURCE] = devfileSource; return devfile; }