Skip to content

Commit

Permalink
feat: add possibility to create an empty workspace
Browse files Browse the repository at this point in the history
Signed-off-by: Oleksii Orel <oorel@redhat.com>
  • Loading branch information
olexii4 committed Aug 10, 2022
1 parent 0d34b5c commit 085061e
Show file tree
Hide file tree
Showing 19 changed files with 216 additions and 41 deletions.
3 changes: 2 additions & 1 deletion .deps/dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@
| [`@types/mime@1.3.2`](https://github.com/DefinitelyTyped/DefinitelyTyped.git) | MIT | clearlydefined |
| [`@types/minimatch@3.0.5`](https://github.com/DefinitelyTyped/DefinitelyTyped.git) | MIT | clearlydefined |
| [`@types/minimist@1.2.2`](https://github.com/DefinitelyTyped/DefinitelyTyped.git) | MIT | clearlydefined |
| [`@types/node-fetch@2.6.2`](https://github.com/DefinitelyTyped/DefinitelyTyped.git) | MIT | clearlydefined |
| [`@types/normalize-package-data@2.4.1`](https://github.com/DefinitelyTyped/DefinitelyTyped.git) | MIT | clearlydefined |
| [`@types/parse-json@4.0.0`](https://www.github.com/DefinitelyTyped/DefinitelyTyped.git) | MIT | clearlydefined |
| [`@types/prettier@2.4.4`](https://github.com/DefinitelyTyped/DefinitelyTyped.git) | MIT | clearlydefined |
Expand Down Expand Up @@ -486,6 +487,7 @@
| [`flat-cache@3.0.4`](https://github.com/royriojas/flat-cache.git) | MIT | clearlydefined |
| [`flatted@3.2.5`](git+https://github.com/WebReflection/flatted.git) | ISC | #2430 |
| [`for-in@1.0.2`](https://github.com/jonschlinkert/for-in.git) | MIT | clearlydefined |
| [`form-data@3.0.1`](git://github.com/form-data/form-data.git) | MIT | clearlydefined |
| [`fragment-cache@0.2.1`](https://github.com/jonschlinkert/fragment-cache.git) | MIT | clearlydefined |
| [`fs-monkey@1.0.3`](https://github.com/streamich/fs-monkey.git) | Unlicense | [clearlydefined](https://clearlydefined.io/definitions/npm/npmjs/-/fs-monkey/1.0.3) |
| `fsevents@2.3.2` | | [clearlydefined](https://clearlydefined.io/definitions/npm/npmjs/-/fsevents/2.3.2) |
Expand Down Expand Up @@ -711,7 +713,6 @@
| [`neo-async@2.6.2`](git@github.com:suguru03/neo-async.git) | MIT | clearlydefined |
| [`nice-try@1.0.5`](https://github.com/electerious/nice-try.git) | MIT | clearlydefined |
| [`no-case@3.0.4`](git://github.com/blakeembrey/change-case.git) | MIT | clearlydefined |
| [`node-fetch@2.6.7`](https://github.com/bitinn/node-fetch.git) | MIT | clearlydefined |
| [`node-forge@1.3.1`](https://github.com/digitalbazaar/forge) | (BSD-3-Clause OR GPL-2.0) | [clearlydefined](https://clearlydefined.io/definitions/npm/npmjs/-/node-forge/1.3.1) |
| [`node-gyp@8.4.1`](git://github.com/nodejs/node-gyp.git) | MIT | #1849 |
| [`node-int64@0.4.0`](https://github.com/broofa/node-int64) | MIT | clearlydefined |
Expand Down
4 changes: 4 additions & 0 deletions .deps/prod.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@
| [`ms@2.0.0`](https://github.com/zeit/ms.git) | MIT | clearlydefined |
| [`nan@2.15.0`](git://github.com/nodejs/nan.git) | MIT | #986 |
| [`nanoid@3.3.4`](https://github.com/ai/nanoid.git) | MIT | clearlydefined |
| [`node-fetch@2.6.7`](https://github.com/bitinn/node-fetch.git) | MIT | clearlydefined |
| [`normalize-url@6.1.0`](https://github.com/sindresorhus/normalize-url.git) | MIT | clearlydefined |
| [`npm-run-path@4.0.1`](https://github.com/sindresorhus/npm-run-path.git) | MIT | clearlydefined |
| [`oauth-sign@0.9.0`](https://github.com/mikeal/oauth-sign) | Apache-2.0 | clearlydefined |
Expand Down Expand Up @@ -428,6 +429,7 @@
| [`toggle-selection@1.0.6`](git+https://github.com/sudodoki/toggle-selection) | MIT | clearlydefined |
| [`toidentifier@1.0.1`](https://github.com/component/toidentifier.git) | MIT | clearlydefined |
| [`tough-cookie@2.5.0`](git://github.com/salesforce/tough-cookie.git) | BSD-3-Clause | clearlydefined |
| [`tr46@0.0.3`](git+https://github.com/Sebmaster/tr46.js.git) | MIT | clearlydefined |
| [`trim-right@1.0.1`](https://github.com/sindresorhus/trim-right.git) | MIT | clearlydefined |
| [`tslib@2.3.1`](https://github.com/Microsoft/tslib.git) | 0BSD | clearlydefined |
| [`tunnel-agent@0.6.0`](https://github.com/mikeal/tunnel-agent) | Apache-2.0 | clearlydefined |
Expand Down Expand Up @@ -455,7 +457,9 @@
| [`vscode-nls@4.1.2`](https://github.com/Microsoft/vscode-nls.git) | MIT | clearlydefined |
| [`vscode-uri@2.1.2`](git+https://github.com/Microsoft/vscode-uri.git) | MIT | clearlydefined |
| [`warning@4.0.3`](https://github.com/BerkeleyTrue/warning.git) | MIT | [CQ22359](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=22359) |
| [`webidl-conversions@3.0.1`](https://github.com/jsdom/webidl-conversions.git) | BSD-2-Clause | clearlydefined |
| [`websocket@1.0.23`](https://github.com/theturtle32/WebSocket-Node.git) | Apache-2.0 | [CQ22360](https://dev.eclipse.org/ipzilla/show_bug.cgi?id=22360) |
| [`whatwg-url@5.0.0`](https://github.com/jsdom/whatwg-url.git) | MIT | clearlydefined |
| [`which@2.0.2`](git://github.com/isaacs/node-which.git) | ISC | clearlydefined |
| [`wrappy@1.0.2`](https://github.com/npm/wrappy) | ISC | clearlydefined |
| [`ws@8.7.0`](https://github.com/websockets/ws.git) | MIT | clearlydefined |
Expand Down
2 changes: 2 additions & 0 deletions packages/dashboard-backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"axios": "^0.21.4",
"fastify": "^3.29.1",
"fs-extra": "9.1.0",
"node-fetch": "^2.6.7",
"querystring": "^0.2.1",
"reflect-metadata": "^0.1.13",
"request": "^2.79.0",
Expand All @@ -49,6 +50,7 @@
"@types/fs-extra": "^9.0.12",
"@types/jest": "^26.0.20",
"@types/node": "^14.14.35",
"@types/node-fetch": "^2.5.7",
"@types/tunnel": "0.0.1",
"@typescript-eslint/eslint-plugin": "^4.31.2",
"@typescript-eslint/parser": "^4.31.2",
Expand Down
6 changes: 3 additions & 3 deletions packages/dashboard-backend/src/api/dockerConfigApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

import { FastifyInstance, FastifyRequest } from 'fastify';
import { baseApiPath } from '../constants/config';
import { dockerConfigSchema, namespacedDockerConfigSchema } from '../constants/schemas';
import { dockerConfigSchema, namespacedSchema } from '../constants/schemas';
import { getDevWorkspaceClient, getToken } from './helper';
import { restParams } from '../typings/models';
import { getSchema } from '../services/helpers';
Expand All @@ -22,7 +22,7 @@ const tags = ['Docker Config'];
export function registerDockerConfigApi(server: FastifyInstance) {
server.get(
`${baseApiPath}/namespace/:namespace/dockerconfig`,
getSchema({ tags, params: namespacedDockerConfigSchema }),
getSchema({ tags, params: namespacedSchema }),
async function (request: FastifyRequest) {
const { namespace } = request.params as restParams.INamespacedParam;
const token = getToken(request);
Expand All @@ -34,7 +34,7 @@ export function registerDockerConfigApi(server: FastifyInstance) {

server.put(
`${baseApiPath}/namespace/:namespace/dockerconfig`,
getSchema({ tags, params: namespacedDockerConfigSchema, body: dockerConfigSchema }),
getSchema({ tags, params: namespacedSchema, body: dockerConfigSchema }),
async function (request: FastifyRequest) {
const { namespace } = request.params as restParams.INamespacedParam;
const dockerCfg = request.body as restParams.IDockerConfigParams;
Expand Down
58 changes: 58 additions & 0 deletions packages/dashboard-backend/src/api/yamlResolverApi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2018-2021 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 { FastifyInstance, FastifyRequest } from 'fastify';
import fetch from 'node-fetch';
import { baseApiPath } from '../constants/config';
import { yamlResolverSchema, namespacedSchema } from '../constants/schemas';
import { getDevWorkspaceClient, getToken } from './helper';
import { restParams } from '../typings/models';
import { getSchema } from '../services/helpers';
import { helpers } from '@eclipse-che/common';

const tags = ['Yaml Resolver'];

export function registerYamlResolverApi(server: FastifyInstance) {
server.post(
`${baseApiPath}/namespace/:namespace/yaml/resolver`,
getSchema({ tags, params: namespacedSchema, body: yamlResolverSchema }),
async function (request: FastifyRequest) {
const { url } = request.body as restParams.IYamlResolverParam;
const { namespace } = request.params as restParams.INamespacedParam;
const token = getToken(request);
const { dockerConfigApi } = await getDevWorkspaceClient(token);

try {
// check user permissions
await dockerConfigApi.read(namespace);
} catch (e) {
throw new Error(`User permissions error. ${helpers.errors.getMessage(e)}`);
}

const response = await fetch(url);
if (!response.ok || response.body === null) {
throw new Error(`Unexpected response ${response.statusText}`);
}

let outputData = '';
try {
for await (const chunk of response.body) {
outputData += chunk.toString();
}
} catch (err) {
throw new Error(`Type error. ${helpers.errors.getMessage(err)}`);
}

return outputData;
},
);
}
21 changes: 11 additions & 10 deletions packages/dashboard-backend/src/constants/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,6 @@ export const namespacedKubeConfigSchema: JSONSchema7 = {
required: ['namespace', 'devworkspaceId'],
};

export const namespacedDockerConfigSchema: JSONSchema7 = {
type: 'object',
properties: {
namespace: {
type: 'string',
},
},
required: ['namespace'],
};

export const namespacedWorkspaceSchema: JSONSchema7 = {
type: 'object',
properties: {
Expand Down Expand Up @@ -137,6 +127,17 @@ export const dockerConfigSchema: JSONSchema7 = {
required: ['dockerconfig'],
};

export const yamlResolverSchema: JSONSchema7 = {
type: 'object',
properties: {
url: {
type: 'string',
pattern: '^http.*.yaml$',
},
},
required: ['url'],
};

export const devworkspaceSchema: JSONSchema7 = {
type: 'object',
properties: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {

import { api } from '@eclipse-che/common';
import { createError } from '../helpers';
import { isLocalRun } from '../../../local-run';

const DEV_WORKSPACE_API_ERROR_LABEL = 'CUSTOM_OBJECTS_API_ERROR';

Expand Down Expand Up @@ -212,8 +213,10 @@ export class DevWorkspaceApi implements IDevWorkspaceApi {
if (error && error.message) {
message = error.message;
} else {
// unexpected error format. Log it and expose to user what we can
console.log('Unexpected error', error);
if (isLocalRun) {
// unexpected error format. Log it and expose to user what we can
console.log('Unexpected error', error);
}
if (error) {
message = error.toString();
}
Expand Down
3 changes: 3 additions & 0 deletions packages/dashboard-backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
} from './local-run/dexHelper';
import { registerFactory } from './factory';
import { namespaceApi } from './api/namespaceApi';
import { registerYamlResolverApi } from './api/yamlResolverApi';

const CHE_HOST = process.env.CHE_HOST as string;

Expand Down Expand Up @@ -109,6 +110,8 @@ registerClusterInfoApi(server);

registerClusterConfigApi(server);

registerYamlResolverApi(server);

server.listen(8080, '0.0.0.0', (err: Error | null, address: string) => {
if (err) {
console.error(err);
Expand Down
4 changes: 4 additions & 0 deletions packages/dashboard-backend/src/typings/models.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ declare namespace restParams {
export interface IDevWorkspaceSpecParam {
devworkspace: V1alpha2DevWorkspace;
}

export interface IYamlResolverParam {
url: string;
}
}

declare module 'restParams' {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ type State = {
};

const EXCLUDED_TARGET_EDITOR_NAMES = ['dirigible', 'jupyter', 'eclipseide', 'code-server'];
const EMPTY_WORKSPACE_TAG = 'Empty';

export class SamplesListGallery extends React.PureComponent<Props, State> {
private static sortByName(a: TargetEditor, b: TargetEditor): number {
Expand All @@ -71,6 +72,15 @@ export class SamplesListGallery extends React.PureComponent<Props, State> {
}
return 0;
}
private static sortByEmptyWorkspaceTag(a: che.DevfileMetaData, b: che.DevfileMetaData): number {
if (a.tags.includes(EMPTY_WORKSPACE_TAG) > b.tags.includes(EMPTY_WORKSPACE_TAG)) {
return -1;
}
if (a.tags.includes(EMPTY_WORKSPACE_TAG) < b.tags.includes(EMPTY_WORKSPACE_TAG)) {
return 1;
}
return 0;
}
private static sortByDisplayName(a: che.DevfileMetaData, b: che.DevfileMetaData): number {
if (a.displayName < b.displayName) {
return -1;
Expand Down Expand Up @@ -186,6 +196,7 @@ export class SamplesListGallery extends React.PureComponent<Props, State> {

return metadata
.sort(SamplesListGallery.sortByDisplayName)
.sort(SamplesListGallery.sortByEmptyWorkspaceTag)
.map(meta => (
<SampleCard
key={meta.links.self}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2018-2021 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 axios from 'axios';
import { helpers } from '@eclipse-che/common';
import { prefix } from './const';

export async function getYamlResolver(namespace: string, location: string): Promise<string> {
try {
const url = new URL(location);
const response =
url.origin === window.location.origin
? await axios.get(url.href)
: await axios.post(`${prefix}/namespace/${namespace}/yaml/resolver`, { url: url.href });
return response.data;
} catch (e) {
throw `Failed to fetch yaml resolver'. ${helpers.errors.getMessage(e)}`;
}
}
11 changes: 10 additions & 1 deletion packages/dashboard-frontend/src/store/DevfileRegistries/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import devfileApi from '../../services/devfileApi';
import { fetchResources, loadResourcesContent } from '../../services/registry/resources';

const WorkspaceClient = container.get(CheWorkspaceClient);
export const DEFAULT_REGISTRY = '/dashboard/static/registry/';

export type DevWorkspaceResources = [devfileApi.DevWorkspace, devfileApi.DevWorkspaceTemplate];

Expand Down Expand Up @@ -174,7 +175,15 @@ export const actionCreators: ActionCreators = {
async (dispatch): Promise<void> => {
dispatch({ type: Type.REQUEST_REGISTRY_METADATA });

const promises = registryUrls.split(' ').map(async url => {
const registries: string[] = registryUrls.split(' ');
if (DEFAULT_REGISTRY) {
if (DEFAULT_REGISTRY.startsWith('http')) {
registries.push(DEFAULT_REGISTRY);
} else {
registries.push(new URL(DEFAULT_REGISTRY, window.location.origin).href);
}
}
const promises = registries.map(async url => {
try {
const metadata = await fetchRegistryMetadata(url);
if (!Array.isArray(metadata) || metadata.length === 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ describe('FactoryResolver store', () => {
ThunkDispatch<AppState, undefined, factoryResolverStore.KnownAction>
>;

const location = 'factory-link';
const location = 'http://factory-link';
await store.dispatch(factoryResolverStore.actionCreators.requestFactoryResolver(location));

const actions = store.getActions();
Expand Down Expand Up @@ -126,7 +126,7 @@ describe('FactoryResolver store', () => {
ThunkDispatch<AppState, undefined, factoryResolverStore.KnownAction>
>;

const location = 'factory-link';
const location = 'http://factory-link';
await store.dispatch(factoryResolverStore.actionCreators.requestFactoryResolver(location));

const actions = store.getActions();
Expand Down Expand Up @@ -161,7 +161,7 @@ describe('FactoryResolver store', () => {
ThunkDispatch<AppState, undefined, factoryResolverStore.KnownAction>
>;

const location = 'factory-link';
const location = 'http://factory-link';
await store.dispatch(factoryResolverStore.actionCreators.requestFactoryResolver(location));

const actions = store.getActions();
Expand Down Expand Up @@ -196,7 +196,7 @@ describe('FactoryResolver store', () => {
ThunkDispatch<AppState, undefined, factoryResolverStore.KnownAction>
>;

const location = 'factory-link';
const location = 'http://factory-link';
await store.dispatch(factoryResolverStore.actionCreators.requestFactoryResolver(location));

const actions = store.getActions();
Expand Down Expand Up @@ -233,7 +233,7 @@ describe('FactoryResolver store', () => {
ThunkDispatch<AppState, undefined, factoryResolverStore.KnownAction>
>;

const location = 'factory-link';
const location = 'http://factory-link';
await store.dispatch(factoryResolverStore.actionCreators.requestFactoryResolver(location));

const actions = store.getActions();
Expand Down Expand Up @@ -284,7 +284,7 @@ describe('FactoryResolver store', () => {
.spyOn(common.helpers.errors, 'isAxiosResponse')
.mockImplementation(() => true);

const location = 'factory-link';
const location = 'http://factory-link';
await expect(
store.dispatch(factoryResolverStore.actionCreators.requestFactoryResolver(location)),
).rejects.toMatch('Failed to request factory resolver');
Expand Down Expand Up @@ -315,7 +315,7 @@ describe('FactoryResolver store', () => {
},
];

const location = 'factory-link';
const location = 'http://factory-link';
await expect(
store.dispatch(factoryResolverStore.actionCreators.requestFactoryResolver(location)),
).rejects.toMatch('The specified link does not contain a valid Devfile.');
Expand Down Expand Up @@ -352,7 +352,7 @@ describe('FactoryResolver store', () => {
.spyOn(common.helpers.errors, 'isAxiosResponse')
.mockReturnValue(true);

const location = 'factory-link';
const location = 'http://factory-link';
await expect(
store.dispatch(factoryResolverStore.actionCreators.requestFactoryResolver(location)),
).rejects.toEqual({
Expand Down
Loading

0 comments on commit 085061e

Please sign in to comment.