Skip to content
This repository has been archived by the owner on Apr 4, 2023. It is now read-only.

Rework reading pod's information for resource monitor plugin #1089

Merged
merged 9 commits into from
May 7, 2021
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
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export class CheServerDevfileServiceImpl implements DevfileService {
@inject(CheK8SServiceImpl)
private k8SService: CheK8SServiceImpl;

private INFRASTRUCTURE_NAMESPACE = 'infrastructureNamespace';

componentVolumeV1toComponentVolumeV2(
componentVolumes?: cheApi.workspace.devfile.DevfileVolume[]
): DevfileComponentVolumeMount[] | undefined {
Expand Down Expand Up @@ -500,7 +502,7 @@ export class CheServerDevfileServiceImpl implements DevfileService {
return gitSource;
}

metadataV1toMetadataV2(metadataV1?: cheApi.workspace.devfile.Metadata): DevfileMetadata {
async metadataV1toMetadataV2(metadataV1?: cheApi.workspace.devfile.Metadata): Promise<DevfileMetadata> {
const devfileMetadataV2: DevfileMetadata = {};
if (metadataV1) {
if (metadataV1.generateName) {
Expand All @@ -518,6 +520,12 @@ export class CheServerDevfileServiceImpl implements DevfileService {
devfileMetadataV2.attributes['metadata-name-field'] = 'name';
}
}
if (!devfileMetadataV2.attributes) {
devfileMetadataV2.attributes = {};
}
const workspace = await this.workspaceService.currentWorkspace();
const workspaceNameSpace = workspace.attributes?.[this.INFRASTRUCTURE_NAMESPACE] || workspace.namespace || '';
devfileMetadataV2.attributes[this.INFRASTRUCTURE_NAMESPACE] = workspaceNameSpace;
return devfileMetadataV2;
}

Expand Down Expand Up @@ -571,10 +579,10 @@ export class CheServerDevfileServiceImpl implements DevfileService {
return devfileContent;
}

devfileV1toDevfileV2(devfileV1: cheApi.workspace.devfile.Devfile): Devfile {
async devfileV1toDevfileV2(devfileV1: cheApi.workspace.devfile.Devfile): Promise<Devfile> {
const devfileV2: Devfile = {
apiVersion: '2.0.0',
metadata: this.metadataV1toMetadataV2(devfileV1.metadata),
metadata: await this.metadataV1toMetadataV2(devfileV1.metadata),
projects: (devfileV1.projects || []).map(project => this.projectV1toProjectV2(project)),
components: (devfileV1.components || []).map(component => this.componentV1toComponentV2(component)),
commands: (devfileV1.commands || []).map(command => this.commandV1toCommandV2(command)),
Expand Down Expand Up @@ -602,10 +610,15 @@ export class CheServerDevfileServiceImpl implements DevfileService {
if (devfileV2.metadata.attributes) {
const attributeKeys = Object.keys(devfileV2.metadata.attributes);
if (attributeKeys.length > 0) {
devfileV1.attributes = devfileV1.attributes || {};
const attributes = devfileV1.attributes || {};
attributeKeys.forEach(attributeName => {
devfileV1.attributes![attributeName] = devfileV2.metadata.attributes![attributeName];
if (attributeName !== this.INFRASTRUCTURE_NAMESPACE) {
attributes[attributeName] = devfileV2.metadata.attributes![attributeName];
}
});
if (Object.keys(attributes).length > 0) {
devfileV1.attributes = attributes;
}
}
}

Expand Down Expand Up @@ -643,7 +656,7 @@ export class CheServerDevfileServiceImpl implements DevfileService {

// grab runtime
const componentStatuses: DevfileComponentStatus[] = [];
const workspaceNameSpace = workspace.attributes?.['infrastructureNamespace'] || workspace.namespace || '';
const workspaceNameSpace = workspace.attributes?.[this.INFRASTRUCTURE_NAMESPACE] || workspace.namespace || '';
const runtime = workspace.runtime;

const machines = runtime?.machines || {};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
apiVersion: 1.0.0
attributes:
multiRoot: 'off'
attributeName: 'attributeValue'
metadata:
name: test
Original file line number Diff line number Diff line change
Expand Up @@ -40,23 +40,23 @@ describe('Test CheServerDevfileServiceImpl', () => {
makeApiClient: k8sServiceMakeApiClientMethod,
} as any;

beforeEach(() => {
beforeEach(async () => {
jest.restoreAllMocks();
jest.resetAllMocks();
const container = new Container();

const workspaceJsonPath = path.resolve(__dirname, '..', '_data', 'workspace-runtime.json');
const workspaceJsonContent = await fs.readFile(workspaceJsonPath, 'utf-8');
const workspaceJson = JSON.parse(workspaceJsonContent);
workspaceServiceCurrentWorkspaceMethod.mockResolvedValue(workspaceJson);

container.bind(CheServerDevfileServiceImpl).toSelf().inSingletonScope();
container.bind(CheServerWorkspaceServiceImpl).toConstantValue(workspaceService);
container.bind(CheK8SServiceImpl).toConstantValue(k8sServiceMock);
cheServerDevfileServiceImpl = container.get(CheServerDevfileServiceImpl);
});

test('get', async () => {
const workspaceJsonPath = path.resolve(__dirname, '..', '_data', 'workspace-runtime.json');
const workspaceJsonContent = await fs.readFile(workspaceJsonPath, 'utf-8');
const workspaceJson = JSON.parse(workspaceJsonContent);
workspaceServiceCurrentWorkspaceMethod.mockResolvedValue(workspaceJson);

const devfile = await cheServerDevfileServiceImpl.get();
expect(devfile).toBeDefined();

Expand Down Expand Up @@ -120,7 +120,6 @@ describe('Test CheServerDevfileServiceImpl', () => {

test('convert v1/v2', async () => {
// convert devfile1 to devfile2 to devfile1 and see if it's the same object

const devfileV1: che.workspace.devfile.Devfile = {
apiVersion: '1.0.0',
metadata: {
Expand All @@ -139,7 +138,8 @@ describe('Test CheServerDevfileServiceImpl', () => {
},
],
};
const convertedToDevfileV2 = cheServerDevfileServiceImpl.devfileV1toDevfileV2(devfileV1);
const convertedToDevfileV2 = await cheServerDevfileServiceImpl.devfileV1toDevfileV2(devfileV1);
expect(convertedToDevfileV2.metadata.attributes?.infrastructureNamespace).toEqual('foo');
const convertedToDevfileV1 = cheServerDevfileServiceImpl.devfileV2toDevfileV1(convertedToDevfileV2);
expect(convertedToDevfileV1).toEqual(devfileV1);
});
Expand All @@ -149,7 +149,7 @@ describe('Test CheServerDevfileServiceImpl', () => {
const devfileContent = await fs.readFile(cheTheiaDevfileYamlPath, 'utf-8');
const devfileV1 = jsYaml.safeLoad(devfileContent);

const convertedDevfileV2 = cheServerDevfileServiceImpl.devfileV1toDevfileV2(devfileV1);
const convertedDevfileV2 = await cheServerDevfileServiceImpl.devfileV1toDevfileV2(devfileV1);
const convertedDevfileV1 = cheServerDevfileServiceImpl.devfileV2toDevfileV1(convertedDevfileV2);
expect(convertedDevfileV1).toEqual(devfileV1);
});
Expand All @@ -159,7 +159,7 @@ describe('Test CheServerDevfileServiceImpl', () => {
const devfileContent = await fs.readFile(cheTheiaDevfileYamlPath, 'utf-8');
const devfileV1 = jsYaml.safeLoad(devfileContent);

const convertedDevfileV2 = cheServerDevfileServiceImpl.devfileV1toDevfileV2(devfileV1);
const convertedDevfileV2 = await cheServerDevfileServiceImpl.devfileV1toDevfileV2(devfileV1);
const convertedDevfileV1 = cheServerDevfileServiceImpl.devfileV2toDevfileV1(convertedDevfileV2);
expect(convertedDevfileV1).toEqual(devfileV1);
});
Expand All @@ -169,7 +169,7 @@ describe('Test CheServerDevfileServiceImpl', () => {
const devfileContent = await fs.readFile(cheTheiaDevfileYamlPath, 'utf-8');
const devfileV1 = jsYaml.safeLoad(devfileContent);

const convertedDevfileV2 = cheServerDevfileServiceImpl.devfileV1toDevfileV2(devfileV1);
const convertedDevfileV2 = await cheServerDevfileServiceImpl.devfileV1toDevfileV2(devfileV1);
const convertedDevfileV1 = cheServerDevfileServiceImpl.devfileV2toDevfileV1(convertedDevfileV2);
expect(convertedDevfileV1).toEqual(devfileV1);
});
Expand All @@ -179,7 +179,7 @@ describe('Test CheServerDevfileServiceImpl', () => {
const devfileContent = await fs.readFile(cheTheiaDevfileYamlPath, 'utf-8');
const devfileV1 = jsYaml.safeLoad(devfileContent);

const convertedDevfileV2 = cheServerDevfileServiceImpl.devfileV1toDevfileV2(devfileV1);
const convertedDevfileV2 = await cheServerDevfileServiceImpl.devfileV1toDevfileV2(devfileV1);
const convertedDevfileV1 = cheServerDevfileServiceImpl.devfileV2toDevfileV1(convertedDevfileV2);
expect(convertedDevfileV1).toEqual(devfileV1);
});
Expand All @@ -189,7 +189,7 @@ describe('Test CheServerDevfileServiceImpl', () => {
const devfileContent = await fs.readFile(cheTheiaDevfileYamlPath, 'utf-8');
const devfileV1 = jsYaml.safeLoad(devfileContent);

const convertedDevfileV2 = cheServerDevfileServiceImpl.devfileV1toDevfileV2(devfileV1);
const convertedDevfileV2 = await cheServerDevfileServiceImpl.devfileV1toDevfileV2(devfileV1);
const convertedDevfileV1 = cheServerDevfileServiceImpl.devfileV2toDevfileV1(convertedDevfileV2);
expect(convertedDevfileV1).toEqual(devfileV1);
});
Expand All @@ -199,7 +199,7 @@ describe('Test CheServerDevfileServiceImpl', () => {
const devfileContent = await fs.readFile(cheTheiaDevfileYamlPath, 'utf-8');
const devfileV1 = jsYaml.safeLoad(devfileContent);

const convertedDevfileV2 = cheServerDevfileServiceImpl.devfileV1toDevfileV2(devfileV1);
const convertedDevfileV2 = await cheServerDevfileServiceImpl.devfileV1toDevfileV2(devfileV1);
const convertedDevfileV1 = cheServerDevfileServiceImpl.devfileV2toDevfileV1(convertedDevfileV2);
expect(convertedDevfileV1).toEqual(devfileV1);
});
Expand All @@ -209,7 +209,7 @@ describe('Test CheServerDevfileServiceImpl', () => {
const devfileContent = await fs.readFile(cheTheiaDevfileYamlPath, 'utf-8');
const devfileV1 = jsYaml.safeLoad(devfileContent);

const convertedDevfileV2 = cheServerDevfileServiceImpl.devfileV1toDevfileV2(devfileV1);
const convertedDevfileV2 = await cheServerDevfileServiceImpl.devfileV1toDevfileV2(devfileV1);
const convertedDevfileV1 = cheServerDevfileServiceImpl.devfileV2toDevfileV1(convertedDevfileV2);
expect(convertedDevfileV1).toEqual(devfileV1);
});
Expand All @@ -219,7 +219,9 @@ describe('Test CheServerDevfileServiceImpl', () => {
const devfileContent = await fs.readFile(cheTheiaDevfileYamlPath, 'utf-8');
const devfileV1 = jsYaml.safeLoad(devfileContent);

const convertedDevfileV2 = cheServerDevfileServiceImpl.devfileV1toDevfileV2(devfileV1);
const convertedDevfileV2 = await cheServerDevfileServiceImpl.devfileV1toDevfileV2(devfileV1);
expect(convertedDevfileV2.metadata.attributes?.['infrastructureNamespace']).toEqual('foo');

const convertedDevfileV1 = cheServerDevfileServiceImpl.devfileV2toDevfileV1(convertedDevfileV2);
expect(convertedDevfileV1).toEqual(devfileV1);
});
Expand Down
12 changes: 10 additions & 2 deletions plugins/resource-monitor-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,19 @@
"*"
],
"devDependencies": {
"@types/jest": "^26",
"ts-jest": "26.4.3",
"jest": "^26.6.3",
"@eclipse-che/plugin": "0.0.1",
"@theia/plugin-packager": "latest",
"@theia/plugin": "next"
},
"dependencies": {},
"dependencies": {
"inversify": "^5.0.1",
"reflect-metadata": "^0.1.13",
"@kubernetes/client-node": "^0.12.1",
"got": "11.8.0"
},
"scripts": {
"prepare": "yarn clean && yarn build && yarn lint:fix && yarn test",
"clean": "rimraf lib",
Expand All @@ -36,7 +44,7 @@
"theiaPlugin": "next"
},
"theiaPlugin": {
"backend": "lib/resource-monitor-plugin.js"
"backend": "lib/plugin.js"
},
"jest": {
"collectCoverage": true,
Expand Down
2 changes: 1 addition & 1 deletion plugins/resource-monitor-plugin/src/constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (c) 2018-2020 Red Hat, Inc.
* Copyright (c) 2021 Red Hat, Inc.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
Expand Down
29 changes: 29 additions & 0 deletions plugins/resource-monitor-plugin/src/inversify-binding.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**********************************************************************
* Copyright (c) 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
***********************************************************************/
import 'reflect-metadata';

import { Container } from 'inversify';
import { K8sHelper } from './k8s-helper';
import { ResourceMonitor } from './resource-monitor';

export class InversifyBinding {
private container: Container;

constructor() {}

public async initBindings(): Promise<Container> {
this.container = new Container();

this.container.bind(K8sHelper).toSelf().inSingletonScope();
this.container.bind(ResourceMonitor).toSelf().inSingletonScope();

return this.container;
}
}
30 changes: 30 additions & 0 deletions plugins/resource-monitor-plugin/src/k8s-helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**********************************************************************
* Copyright (c) 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
***********************************************************************/
import * as k8s from '@kubernetes/client-node';

import { injectable } from 'inversify';

@injectable()
export class K8sHelper {
private k8sAPI: k8s.CoreV1Api;

initConfig(): k8s.KubeConfig {
return new k8s.KubeConfig();
}

getCoreApi(): k8s.CoreV1Api {
if (!this.k8sAPI) {
const kc = this.initConfig();
kc.loadFromDefault();
this.k8sAPI = kc.makeApiClient(k8s.CoreV1Api);
}
return this.k8sAPI;
}
}
20 changes: 1 addition & 19 deletions plugins/resource-monitor-plugin/src/objects.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**********************************************************************
* Copyright (c) 2018-2020 Red Hat, Inc.
* Copyright (c) 2021 Red Hat, Inc.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
Expand All @@ -21,24 +21,6 @@ export interface Resource {
memory: string;
}

export interface Resources {
limits: Resource;
requests: Resource;
}

export interface PodContainer {
name: string;
resources: Resources;
}

export interface Spec {
containers: PodContainer[];
}

export interface Pod {
spec: Spec;
}

export interface Metrics {
containers: MetricContainer[];
}
Expand Down
33 changes: 33 additions & 0 deletions plugins/resource-monitor-plugin/src/plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**********************************************************************
* Copyright (c) 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
***********************************************************************/

import 'reflect-metadata';

import * as che from '@eclipse-che/plugin';
import * as theia from '@theia/plugin';

import { InversifyBinding } from './inversify-binding';
import { ResourceMonitor } from './resource-monitor';

let resourceMonitorPLugin: ResourceMonitor;

export async function start(context: theia.PluginContext): Promise<void> {
const inversifyBinding = new InversifyBinding();
const container = await inversifyBinding.initBindings();
const namespace = await getNamespace();
resourceMonitorPLugin = container.get(ResourceMonitor);
resourceMonitorPLugin.start(context, namespace);
}

export async function getNamespace(): Promise<string> {
// get namespace from devfile service
const devfile = await che.devfile.get();
return devfile.metadata?.attributes ? devfile.metadata.attributes.infrastructureNamespace : '';
}
Loading