Skip to content
This repository was archived by the owner on Aug 25, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 15 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,40 @@ The DevWorkspace Client is a library for interacting with DevWorkspaces on your
## Examples

Browser side using kubernetes Rest API:

```typescript
import { RestApi } from '@eclipse-che/devworkspace-client';
import axios from 'axios';

const restApiClient = new RestApi(this.axios)
const workspaceApi = restApiClient.workspaceApi;
const promise = workspaceApi.getAllWorkspaces('my_namespace');
promise.then((workspaces) => {
// process workspaces received from my_namespace
const devworkspaceApi = restApiClient.devworkspaceApi;
const promise = devworkspaceApi.getAllDevWorkspaces('my_namespace');
promise.then((devworkspaces) => {
// process devworkspaces received from my_namespace
});
```

Node side using @kubernetes/client-node:

```typescript
import 'reflect-metadata';
import { container, INVERSIFY_TYPES } from '@eclipse-che/devworkspace-client';

const devWorkspaceClient = container.get(INVERSIFY_TYPES.IDevWorkspaceClient);
const nodeApi = devWorkspaceClient.getNodeApi({
const devworkspaceClient = container.get(INVERSIFY_TYPES.IDevWorkspaceClient);
const nodeApi = devworkspaceClient.getNodeApi({
inCluster: false
});
const workspaceApi = nodeApi.workspaceApi;
const promise = workspaceApi.listInNamespace('my_namespace');
promise.then((workspaces) => {
// process workspaces received from my_namespace
const devworkspaceApi = nodeApi.devworkspaceApi;
const promise = devworkspaceApi.listInNamespace('my_namespace');
promise.then((devworkspaces) => {
// process devworkspaces received from my_namespace
});
```


## Developer support

### Getting Started

1. Install prerequisite tooling:
- yarn
- node
Expand All @@ -48,13 +50,14 @@ promise.then((workspaces) => {
- Run `yarn test`

### Integration tests

Integration tests can be run locally by using `export INTEGRATION_TESTS=true`. Refer to the Environment variables section to learn more.

**The devworkspace-controller must be on the cluster before running the integration tests.**

### Environment variables
`INTEGRATION_TESTS`: When the INTEGRATION_TESTS environment variable is defined and it's value is true, the integration tests will run against your currently authenticated cluster.

`INTEGRATION_TESTS`: When the INTEGRATION_TESTS environment variable is defined and it's value is true, the integration tests will run against your currently authenticated cluster.

## License

Expand Down
8 changes: 4 additions & 4 deletions src/browser/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ import { RestDevWorkspaceApi } from './workspace-api';

export class RestApi implements IDevWorkspaceClientApi {
private _axios: AxiosInstance;
private _workspaceApi: IDevWorkspaceApi;
private _devworkspaceApi: IDevWorkspaceApi;
private _templateApi: IDevWorkspaceTemplateApi;
private _cheApi: ICheApi;
private apiEnabled: boolean | undefined;

constructor(axios: AxiosInstance) {
this._axios = axios;
this._workspaceApi = new RestDevWorkspaceApi(axios);
this._devworkspaceApi = new RestDevWorkspaceApi(axios);
this._templateApi = new RestDevWorkspaceTemplateApi(axios);
this._cheApi = new RestCheApi(axios);
}
Expand All @@ -41,8 +41,8 @@ export class RestApi implements IDevWorkspaceClientApi {
this._axios = axios;
}

get workspaceApi(): IDevWorkspaceApi {
return this._workspaceApi;
get devworkspaceApi(): IDevWorkspaceApi {
return this._devworkspaceApi;
}

get templateApi(): IDevWorkspaceTemplateApi {
Expand Down
4 changes: 2 additions & 2 deletions src/browser/template-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ export class RestDevWorkspaceTemplateApi implements IDevWorkspaceTemplateApi {

async getByName(
namespace: string,
workspaceName: string
name: string
): Promise<IDevWorkspaceTemplate> {
try {
const resp = await this._axios.get(
`/apis/${devWorkspaceApiGroup}/${devworkspaceVersion}/namespaces/${namespace}/${devworkspaceTemplateSubresource}/${workspaceName}`
`/apis/${devWorkspaceApiGroup}/${devworkspaceVersion}/namespaces/${namespace}/${devworkspaceTemplateSubresource}/${name}`
);
return resp.data;
} catch (e) {
Expand Down
6 changes: 3 additions & 3 deletions src/browser/workspace-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ export class RestDevWorkspaceApi implements IDevWorkspaceApi {

async getByName(
namespace: string,
workspaceName: string
name: string
): Promise<IDevWorkspace> {
try {
const resp = await this._axios.get(
`/apis/${devWorkspaceApiGroup}/${devworkspaceVersion}/namespaces/${namespace}/${devworkspacePluralSubresource}/${workspaceName}`
`/apis/${devWorkspaceApiGroup}/${devworkspaceVersion}/namespaces/${namespace}/${devworkspacePluralSubresource}/${name}`
);
return resp.data;
} catch (e) {
Expand Down Expand Up @@ -92,7 +92,7 @@ export class RestDevWorkspaceApi implements IDevWorkspaceApi {
}
if (!found) {
throw new Error(
`Was not able to find a workspace with name ${name} in namespace ${namespace}`
`Was not able to find a devworkspace with name ${name} in namespace ${namespace}`
);
}
return found;
Expand Down
2 changes: 1 addition & 1 deletion src/node/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export class NodeRequestError extends Error {
this.response = (error as any).response;
this.request = (error as any).request;
if ((this.status === -1 || !this.status) && (!this.response || (this.response && !this.response.status))) {
this.message = `network issues occured while requesting "${error.url}".`;
this.message = `network issues occurred while requesting "${error.url}".`;
} else if (error.body) {
this.message = error.body.message;
} else {
Expand Down
6 changes: 3 additions & 3 deletions src/node/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export class NodeApi implements IDevWorkspaceClientApi {

constructor(
@inject(INVERSIFY_TYPES.IDevWorkspaceNodeTemplateApi) private _templateApi: IDevWorkspaceTemplateApi,
@inject(INVERSIFY_TYPES.IDevWorkspaceNodeApi) private _workspaceApi: IDevWorkspaceApi,
@inject(INVERSIFY_TYPES.IDevWorkspaceNodeApi) private _devworkspaceApi: IDevWorkspaceApi,
@inject(INVERSIFY_TYPES.IDevWorkspaceNodeCheApi) private _cheApi: ICheApi
) {}

Expand All @@ -41,8 +41,8 @@ export class NodeApi implements IDevWorkspaceClientApi {
return this._templateApi;
}

get workspaceApi(): IDevWorkspaceApi {
return this._workspaceApi;
get devworkspaceApi(): IDevWorkspaceApi {
return this._devworkspaceApi;
}

get cheApi(): ICheApi {
Expand Down
2 changes: 1 addition & 1 deletion src/node/inversify.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ container.bind<interfaces.Factory<IDevWorkspaceClientApi>>(INVERSIFY_TYPES.INode
if (nodeConfig.inCluster) {
if (!isInCluster()) {
throw new Error(
'Recieved error message when attempting to load authentication from cluster. Most likely you are not running inside of a container.'
'Received error message when attempting to load authentication from cluster. Most likely you are not running inside of a container.'
);
}
kc.loadFromCluster();
Expand Down
4 changes: 2 additions & 2 deletions src/node/template-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ export class NodeDevWorkspaceTemplateApi implements IDevWorkspaceTemplateApi {
}
}

async getByName(namespace: string, workspaceName: string): Promise<IDevWorkspaceTemplate> {
async getByName(namespace: string, name: string): Promise<IDevWorkspaceTemplate> {
try {
const resp = await this.customObjectAPI.getNamespacedCustomObject(
devWorkspaceApiGroup,
devworkspaceVersion,
namespace,
devworkspaceTemplateSubresource,
workspaceName
name
);
return resp.body as IDevWorkspaceTemplate;
} catch (e) {
Expand Down
4 changes: 2 additions & 2 deletions src/node/workspace-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,15 @@ export class NodeDevWorkspaceApi implements IDevWorkspaceApi {

async getByName(
namespace: string,
workspaceName: string
name: string
): Promise<IDevWorkspace> {
try {
const resp = await this.customObjectAPI.getNamespacedCustomObject(
devWorkspaceApiGroup,
devworkspaceVersion,
namespace,
devworkspacePluralSubresource,
workspaceName
name
);
return resp.body as IDevWorkspace;
} catch (e) {
Expand Down
8 changes: 4 additions & 4 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export interface IDevWorkspaceClient {
export interface IDevWorkspaceApi {
config: k8s.KubeConfig | AxiosInstance;
listInNamespace(namespace: string): Promise<IDevWorkspace[]>;
getByName(namespace: string, workspaceName: string): Promise<IDevWorkspace>;
getByName(namespace: string, name: string): Promise<IDevWorkspace>;
create(
devfile: IDevWorkspaceDevfile,
routingClass: string,
Expand All @@ -34,14 +34,14 @@ export interface IDevWorkspaceApi {
export interface IDevWorkspaceTemplateApi {
config: k8s.KubeConfig | AxiosInstance;
listInNamespace(namespace: string): Promise<IDevWorkspaceTemplate[]>;
getByName(namespace: string, workspaceName: string): Promise<IDevWorkspaceTemplate>;
getByName(namespace: string, name: string): Promise<IDevWorkspaceTemplate>;
delete(namespace: string, name: string): Promise<void>;
create(template: IDevWorkspaceTemplate): Promise<IDevWorkspaceTemplate>;
}

export interface IDevWorkspaceClientApi {
config: k8s.KubeConfig | AxiosInstance;
workspaceApi: IDevWorkspaceApi;
devworkspaceApi: IDevWorkspaceApi;
templateApi: IDevWorkspaceTemplateApi;
cheApi: ICheApi;
isDevWorkspaceApiEnabled(): Promise<boolean>;
Expand Down Expand Up @@ -75,7 +75,7 @@ export interface IDevWorkspace {
status: {
ideUrl: string;
phase: string;
workspaceId: string;
devworkspaceId: string;
message?: string;
};
}
Expand Down
16 changes: 8 additions & 8 deletions test/integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,37 +50,37 @@ describe('DevWorkspace API integration testing against cluster', () => {
expect(projectExists).toBe(true);

// check that creation works
const newDevWorkspace = await nodeApi.workspaceApi.create(devfile, 'che', true);
const newDevWorkspace = await nodeApi.devworkspaceApi.create(devfile, 'che', true);
expect(newDevWorkspace.metadata.name).toBe(name);
expect(newDevWorkspace.metadata.namespace).toBe(namespace);

// check that retrieval works
const allWorkspaces = await nodeApi.workspaceApi.listInNamespace(namespace);
const allWorkspaces = await nodeApi.devworkspaceApi.listInNamespace(namespace);
expect(allWorkspaces.length).toBe(1);
const firstDevWorkspace = allWorkspaces[0];
expect(firstDevWorkspace.metadata.name).toBe(name);
expect(firstDevWorkspace.metadata.namespace).toBe(namespace);

const singleNamespace = await nodeApi.workspaceApi.getByName(namespace, name);
const singleNamespace = await nodeApi.devworkspaceApi.getByName(namespace, name);
expect(singleNamespace.metadata.name).toBe(name);
expect(singleNamespace.metadata.namespace).toBe(namespace);

// check that updating works
const changedWorkspace = await nodeApi.workspaceApi.changeStatus(namespace, name, false);
const changedWorkspace = await nodeApi.devworkspaceApi.changeStatus(namespace, name, false);
expect(changedWorkspace.spec.started).toBe(false);

await delay(2000);
const currentDevWorkspace = await nodeApi.workspaceApi.getByName(namespace, name);
const currentDevWorkspace = await nodeApi.devworkspaceApi.getByName(namespace, name);
const sampleRouting = 'sample';
currentDevWorkspace.spec.routingClass = sampleRouting;

const updatedWorkspace = await nodeApi.workspaceApi.update(currentDevWorkspace);
const updatedWorkspace = await nodeApi.devworkspaceApi.update(currentDevWorkspace);
expect(updatedWorkspace.spec.routingClass).toBe(sampleRouting);

// check that deletion works
await nodeApi.workspaceApi.delete(namespace, name);
await nodeApi.devworkspaceApi.delete(namespace, name);
await delay(5000);
const finalNamespaces = await nodeApi.workspaceApi.listInNamespace(namespace);
const finalNamespaces = await nodeApi.devworkspaceApi.listInNamespace(namespace);
expect(finalNamespaces.length).toBe(0);

done();
Expand Down