From 9efeb046d228f1978d8dc17f8b8c6305a56d95ed Mon Sep 17 00:00:00 2001 From: Oleksii Kurinnyi Date: Wed, 8 Sep 2021 14:11:30 +0300 Subject: [PATCH] fix: various fixes --- packages/dashboard-backend/src/index.ts | 9 ++++-- .../src/services/DevWorkspaceWatcher.ts | 3 +- .../dashboard-backend/src/services/helpers.ts | 25 ----------------- .../src/services/kubeclient/helpers/index.ts | 28 ++++++++----------- .../src/services/kubeclient/keycloak.ts | 6 ++-- .../devWorkspace/template/metadata.ts | 2 +- .../src/services/devfileApi/typeguards.ts | 1 - .../src/services/keycloak/setup.ts | 5 ++-- .../src/services/workspace-adapter/index.ts | 11 ++++---- .../devworkspace/converters/index.ts | 4 ++- .../store/Workspaces/devWorkspaces/index.ts | 11 ++++++-- 11 files changed, 45 insertions(+), 60 deletions(-) diff --git a/packages/dashboard-backend/src/index.ts b/packages/dashboard-backend/src/index.ts index a2277c44b..695fc8961 100644 --- a/packages/dashboard-backend/src/index.ts +++ b/packages/dashboard-backend/src/index.ts @@ -11,7 +11,7 @@ */ import 'reflect-metadata'; -import fastify, { FastifyRequest } from 'fastify'; +import fastify from 'fastify'; import args from 'args'; import { registerStaticServer } from './static'; import { registerDevworkspaceWebsocketWatcher } from './api/devworkspaceWebsocketWatcher'; @@ -21,6 +21,7 @@ import { registerTemplateApi } from './api/templateApi'; import { registerCheServerApiProxy } from './cheServerApiProxy'; import { registerCors } from './cors'; import { registerSwagger } from './swagger'; +import { HttpError } from '@kubernetes/client-node'; const CHE_HOST = process.env.CHE_HOST as string; @@ -48,8 +49,10 @@ server.addContentTypeParser( try { const json = JSON.parse(body as string); done(null, json); - } catch (err) { - done(new Error('Bad Request'), undefined); + } catch (e) { + const error = e as HttpError; + error.statusCode = 400; + done(error, undefined); } } ); diff --git a/packages/dashboard-backend/src/services/DevWorkspaceWatcher.ts b/packages/dashboard-backend/src/services/DevWorkspaceWatcher.ts index 189f7c45c..9a6909eba 100644 --- a/packages/dashboard-backend/src/services/DevWorkspaceWatcher.ts +++ b/packages/dashboard-backend/src/services/DevWorkspaceWatcher.ts @@ -10,6 +10,7 @@ * Red Hat, Inc. - initial API and implementation */ +import { getMessage } from '@eclipse-che/common/lib/helpers/errors'; import { IDevWorkspaceCallbacks } from '../devworkspace-client'; import { DwClientProvider } from './kubeclient/dwClientProvider'; @@ -50,7 +51,7 @@ class DevWorkspaceWatcher { } this.unsubscribeFunction = unsubscribeFunction; } catch (error) { - this.callbacks.onError((error as any).toString()); + this.callbacks.onError(getMessage(error)); throw error; } } diff --git a/packages/dashboard-backend/src/services/helpers.ts b/packages/dashboard-backend/src/services/helpers.ts index 846f685ef..b635c3e4d 100644 --- a/packages/dashboard-backend/src/services/helpers.ts +++ b/packages/dashboard-backend/src/services/helpers.ts @@ -27,28 +27,3 @@ export function getSchema(additionalParams: restParams.ISchemaParams): { schema: return {schema}; } - -export function getErrorMessage(error: unknown): string { - if (!error) { - return ''; - } - if (isError(error) && error.message) { - return error.message; - } - if (isAxiosResponse(error)) { - if (error.data.message && typeof error.data.message === 'string') { - return error.data.message; - } else { - return JSON.stringify(error.data); - } - } - return JSON.stringify(error); -} - -function isError(error: unknown): error is Error { - return (error as Error).message !== undefined; -} - -function isAxiosResponse(response: unknown): response is AxiosResponse { - return (response as AxiosResponse).status !== undefined && (response as AxiosResponse).data !== undefined; -} diff --git a/packages/dashboard-backend/src/services/kubeclient/helpers/index.ts b/packages/dashboard-backend/src/services/kubeclient/helpers/index.ts index 07300fa37..9f5cfb1e3 100644 --- a/packages/dashboard-backend/src/services/kubeclient/helpers/index.ts +++ b/packages/dashboard-backend/src/services/kubeclient/helpers/index.ts @@ -10,6 +10,7 @@ * Red Hat, Inc. - initial API and implementation */ +import { getMessage } from '@eclipse-che/common/lib/helpers/errors'; import * as k8s from '@kubernetes/client-node'; const projectApiGroup = 'project.openshift.io'; @@ -18,24 +19,19 @@ export async function isOpenShift(apisApi: k8s.ApisApi): Promise { try { return findApi(apisApi, projectApiGroup); } catch (e) { - console.log('Can\'t evaluate target platform: ', e); - return e as boolean; + throw new Error(`Can't evaluate target platform: ${getMessage(e)}`); } } async function findApi(apisApi: k8s.ApisApi, apiName: string, version?: string): Promise { - try { - const resp = await apisApi.getAPIVersions(); - const groups = resp.body.groups; - const filtered = - groups.some((apiGroup: k8s.V1APIGroup) => { - if (version) { - return apiGroup.name === apiName && apiGroup.versions.filter(versionGroup => versionGroup.version === version).length > 0; - } - return apiGroup.name === apiName; - }); - return filtered; - } catch (e) { - return false; - } + const resp = await apisApi.getAPIVersions(); + const groups = resp.body.groups; + const filtered = + groups.some((apiGroup: k8s.V1APIGroup) => { + if (version) { + return apiGroup.name === apiName && apiGroup.versions.filter(versionGroup => versionGroup.version === version).length > 0; + } + return apiGroup.name === apiName; + }); + return filtered; } diff --git a/packages/dashboard-backend/src/services/kubeclient/keycloak.ts b/packages/dashboard-backend/src/services/kubeclient/keycloak.ts index 34f9ea44e..0cbdd1ccb 100644 --- a/packages/dashboard-backend/src/services/kubeclient/keycloak.ts +++ b/packages/dashboard-backend/src/services/kubeclient/keycloak.ts @@ -11,7 +11,7 @@ */ import axios from 'axios'; -import { getErrorMessage } from '../helpers'; +import { getMessage } from '@eclipse-che/common/lib/helpers/errors'; import { isCheServerApiProxyRequired } from '../../index'; import * as https from 'https'; import { URL } from 'url'; @@ -50,7 +50,7 @@ export async function validateToken(keycloakToken: string): Promise { throw { statusCode, error: statusText, - message: `Failed to validate token: ${getErrorMessage(e)}` + message: `Failed to validate token: ${getMessage(e)}` }; } } @@ -81,7 +81,7 @@ async function evaluateKeycloakEndpointUrl(): Promise { throw { statusCode, error: statusText, - message: `Failed to fetch keycloak settings: ${getErrorMessage(e)}` + message: `Failed to fetch keycloak settings: ${getMessage(e)}` }; } } diff --git a/packages/dashboard-frontend/src/services/devfileApi/devWorkspace/template/metadata.ts b/packages/dashboard-frontend/src/services/devfileApi/devWorkspace/template/metadata.ts index ded202eff..c8685689f 100644 --- a/packages/dashboard-frontend/src/services/devfileApi/devWorkspace/template/metadata.ts +++ b/packages/dashboard-frontend/src/services/devfileApi/devWorkspace/template/metadata.ts @@ -13,4 +13,4 @@ import { V1alpha2DevWorkspaceTemplateMetadata } from '@devfile/api'; export type DevWorkspaceTemplateMetadata = V1alpha2DevWorkspaceTemplateMetadata - & Required>; + & Required>; diff --git a/packages/dashboard-frontend/src/services/devfileApi/typeguards.ts b/packages/dashboard-frontend/src/services/devfileApi/typeguards.ts index 631d986d4..f45087113 100644 --- a/packages/dashboard-frontend/src/services/devfileApi/typeguards.ts +++ b/packages/dashboard-frontend/src/services/devfileApi/typeguards.ts @@ -66,7 +66,6 @@ export function isDevWorkspaceTemplate(template: unknown): template is devfileAp export function isDevWorkspaceTemplateMetadata(metadata: unknown): metadata is devfileApi.DevWorkspaceTemplateMetadata { return metadata !== undefined - && (metadata as devfileApi.DevWorkspaceTemplateMetadata).labels !== undefined && (metadata as devfileApi.DevWorkspaceTemplateMetadata).name !== undefined && (metadata as devfileApi.DevWorkspaceTemplateMetadata).namespace !== undefined; } diff --git a/packages/dashboard-frontend/src/services/keycloak/setup.ts b/packages/dashboard-frontend/src/services/keycloak/setup.ts index bd758d219..6f81ea188 100644 --- a/packages/dashboard-frontend/src/services/keycloak/setup.ts +++ b/packages/dashboard-frontend/src/services/keycloak/setup.ts @@ -136,12 +136,13 @@ export class KeycloakSetupService { return settings; } catch (e) { if (common.helpers.errors.isAxiosError(e) && e.response?.status === 404) { + // not found, which mean Che Server is configured to be run without keycloak. return; } let errorMessage = 'Cannot get Keycloak settings'; - if (common.helpers.errors.isAxiosError(e) && e.response?.status) { - errorMessage += `: ${e.response.status} ${e.response.statusText}`; + if (common.helpers.errors.isAxiosError(e)) { + errorMessage += ': ' + common.helpers.errors.getMessage(e); } else { errorMessage += '. Response is not available, please check the Network tab of Developer tools.'; } diff --git a/packages/dashboard-frontend/src/services/workspace-adapter/index.ts b/packages/dashboard-frontend/src/services/workspace-adapter/index.ts index ded260ae1..0fa835b45 100644 --- a/packages/dashboard-frontend/src/services/workspace-adapter/index.ts +++ b/packages/dashboard-frontend/src/services/workspace-adapter/index.ts @@ -21,8 +21,6 @@ import { getId, getStatus } from './helper'; import devfileApi, { isDevfileV2, isDevWorkspace } from '../devfileApi'; import { devWorkspaceKind } from '../devfileApi/devWorkspace'; -const ROUTING_CLASS = 'che'; - export interface Workspace { readonly ref: che.Workspace | devfileApi.DevWorkspace; @@ -239,15 +237,18 @@ export class WorkspaceAdapter if (isCheWorkspace(this.workspace)) { this.workspace.devfile = devfile as che.WorkspaceDevfile; } else { + const workspace = this.workspace as devfileApi.DevWorkspace; const converted = devfileToDevWorkspace( devfile as devfileApi.Devfile, - ROUTING_CLASS, - this.status === DevWorkspaceStatus.RUNNING + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + workspace.spec.routingClass!, + workspace.spec.started ); if (isDevWorkspace(converted)) { (this.workspace as devfileApi.DevWorkspace) = converted; } else { - console.error(`WorkspaceAdapter: the received devworkspace either has wrong "kind" (not ${devWorkspaceKind}) or lacks some of mandatory : `, converted); + console.error(`WorkspaceAdapter: the received devworkspace either has wrong "kind" (not ${devWorkspaceKind}) or lacks some of mandatory fields: `, converted); + throw new Error('Unexpected error happened. Please check the Console tab of Developer tools.'); } } } diff --git a/packages/dashboard-frontend/src/services/workspace-client/devworkspace/converters/index.ts b/packages/dashboard-frontend/src/services/workspace-client/devworkspace/converters/index.ts index a4987f2f0..a414f438b 100644 --- a/packages/dashboard-frontend/src/services/workspace-client/devworkspace/converters/index.ts +++ b/packages/dashboard-frontend/src/services/workspace-client/devworkspace/converters/index.ts @@ -26,6 +26,8 @@ export function devfileToDevWorkspace(devfile: devfileApi.Devfile, routingClass: name: devfile.metadata.name, namespace: devfile.metadata.namespace, annotations: devWorkspaceAnnotations, + labels: {}, + uid: '', }, spec: { started, @@ -34,7 +36,7 @@ export function devfileToDevWorkspace(devfile: devfileApi.Devfile, routingClass: components: [] } } - } as devfileApi.DevWorkspaceLike as devfileApi.DevWorkspace; + } as devfileApi.DevWorkspace; if (devfile.projects) { template.spec.template.projects = devfile.projects; } diff --git a/packages/dashboard-frontend/src/store/Workspaces/devWorkspaces/index.ts b/packages/dashboard-frontend/src/store/Workspaces/devWorkspaces/index.ts index 116274e18..41f5a5427 100644 --- a/packages/dashboard-frontend/src/store/Workspaces/devWorkspaces/index.ts +++ b/packages/dashboard-frontend/src/store/Workspaces/devWorkspaces/index.ts @@ -19,12 +19,13 @@ import { DevWorkspaceStatus } from '../../../services/helpers/types'; import { createObject } from '../../helpers'; import { DevWorkspaceClient, DEVWORKSPACE_NEXT_START_ANNOTATION, IStatusUpdate } from '../../../services/workspace-client/devworkspace/devWorkspaceClient'; import { CheWorkspaceClient } from '../../../services/workspace-client/cheworkspace/cheWorkspaceClient'; -import devfileApi from '../../../services/devfileApi'; +import devfileApi, { isDevWorkspace } from '../../../services/devfileApi'; import { deleteLogs, mergeLogs } from '../logs'; import { getDefer, IDeferred } from '../../../services/helpers/deferred'; import { DisposableCollection } from '../../../services/helpers/disposable'; import { selectDwPluginsList } from '../../Plugins/devWorkspacePlugins/selectors'; import { getId } from '../../../services/workspace-adapter/helper'; +import { devWorkspaceKind } from '../../../services/devfileApi/devWorkspace'; const cheWorkspaceClient = container.get(CheWorkspaceClient); const devWorkspaceClient = container.get(DevWorkspaceClient); @@ -205,7 +206,13 @@ export const actionCreators: ActionCreators = { // If the workspace has DEVWORKSPACE_NEXT_START_ANNOTATION then update the devworkspace with the DEVWORKSPACE_NEXT_START_ANNOTATION annotation value and then start the devworkspace const state = getState(); const plugins = selectDwPluginsList(state); - const storedDevWorkspace = JSON.parse(workspace.metadata.annotations[DEVWORKSPACE_NEXT_START_ANNOTATION]) as devfileApi.DevWorkspace; + + const storedDevWorkspace = JSON.parse(workspace.metadata.annotations[DEVWORKSPACE_NEXT_START_ANNOTATION]) as unknown; + if (!isDevWorkspace(storedDevWorkspace)) { + console.error(`The stored devworkspace either has wrong "kind" (not ${devWorkspaceKind}) or lacks some of mandatory fields: `, storedDevWorkspace); + throw new Error('Unexpected error happened. Please check the Console tab of Developer tools.'); + } + delete workspace.metadata.annotations[DEVWORKSPACE_NEXT_START_ANNOTATION]; workspace.spec.template = storedDevWorkspace.spec.template; workspace.spec.started = true;