Skip to content

Commit

Permalink
CodeLens to apply and delete a k8s YAML file
Browse files Browse the repository at this point in the history
Closes #2873

Signed-off-by: David Thompson <[email protected]>
  • Loading branch information
datho7561 committed Nov 1, 2023
1 parent 3d3aebb commit 358bfee
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 0 deletions.
6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@
"onCommand:openshift.oc.about",
"onCommand:openshift.output",
"onCommand:openshift.create",
"onCommand:openshift.delete",
"onCommand:openshift.open.developerConsole",
"onCommand:openshift.open.developerConsole.palette",
"onCommand:openshift.explorer.addCluster",
Expand Down Expand Up @@ -263,6 +264,11 @@
"title": "Create",
"category": "OpenShift"
},
{
"command": "openshift.delete",
"title": "Delete",
"category": "OpenShift"
},
{
"command": "clusters.openshift.build.start",
"title": "Start Build",
Expand Down
2 changes: 2 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { setupWorkspaceDevfileContext } from './util/workspace';
import { registerCommands } from './vscommand';
import { OpenShiftTerminalManager } from './webview/openshift-terminal/openShiftTerminal';
import { WelcomePage } from './welcomePage';
import { registerYamlHandlers } from './yaml/yamlDocumentFeatures';

import fsx = require('fs-extra');

Expand Down Expand Up @@ -104,6 +105,7 @@ export async function activate(extensionContext: ExtensionContext): Promise<unkn
ComponentsTreeDataProvider.instance.createTreeView('openshiftComponentsView'),
setupWorkspaceDevfileContext(),
window.registerWebviewViewProvider('openShiftTerminalView', OpenShiftTerminalManager.getInstance(), { webviewOptions: { retainContextWhenHidden: true, } }),
...registerYamlHandlers(),
];
disposable.forEach((value) => extensionContext.subscriptions.push(value));

Expand Down
11 changes: 11 additions & 0 deletions src/oc/ocWrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,17 @@ export class Oc {
);
}

/**
* Delete the Kubernetes object described by the given file.
*
* @param file the file containing the spec of the kubernetes object to delete
*/
public async deleteKubernetesObjectFromFile(file: string): Promise<void> {
await CliChannel.getInstance().executeTool(
new CommandText('oc', 'delete', [new CommandOption('-f', file)])
);
}

/**
* Returns the username of the current user.
*
Expand Down
65 changes: 65 additions & 0 deletions src/yaml/yamlDocumentFeatures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*-----------------------------------------------------------------------------------------------
* Copyright (c) Red Hat, Inc. All rights reserved.
* Licensed under the MIT License. See LICENSE file in the project root for license information.
*-----------------------------------------------------------------------------------------------*/

import { KubernetesObject } from '@kubernetes/client-node';
import { load as loadYaml } from 'js-yaml';
import * as vscode from 'vscode';

const YAML_SELECTOR: vscode.DocumentSelector = {
language: 'yaml',
scheme: 'file'
};

const RANGE: vscode.Range = new vscode.Range(new vscode.Position(0, 0), new vscode.Position(0, 1));

export function registerYamlHandlers(): vscode.Disposable[] {
const disposables: vscode.Disposable[] = [];
disposables.push(
vscode.languages.registerCodeLensProvider(YAML_SELECTOR, new YamlCodeLensProvider()));
return disposables;
}

class YamlCodeLensProvider implements vscode.CodeLensProvider {
provideCodeLenses(document: vscode.TextDocument, _token: vscode.CancellationToken): vscode.ProviderResult<vscode.CodeLens[]> {

try {

const objectTexts: string[] = document.getText().split(/(?:^---\r?\n)|(?:\n---\r?\n)/).filter(text => text && text.length > 0);

for (const objectText of objectTexts) {
const yaml = loadYaml(objectText) as KubernetesObject;

// heuristic to check if it's a k8s yaml
if (!yaml.apiVersion || !yaml.kind || !yaml.metadata) {
return [];
}
}

} catch (e) {
return [];
}

return [
{
isResolved: true,
range: RANGE,
command: {
command: 'openshift.create',
title: 'Apply YAML to cluster',
tooltip: 'Performs `kubectl apply -f` on this file'
}
},
{
isResolved: true,
range: RANGE,
command: {
command: 'openshift.delete',
title: 'Delete YAML from cluster',
tooltip: 'Performs `kubectl delete -f` on this file'
}
}
];
}
}
43 changes: 43 additions & 0 deletions src/yamlFileCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,47 @@ export class YamlFileCommands {
await OcWrapper.Instance.createKubernetesObjectFromFile(document.fileName);
return 'Resources were successfully created.';
}

@vsCommand('openshift.delete')
@clusterRequired()
public static async delete(): Promise<string | null> {
const document = window.activeTextEditor ? window.activeTextEditor.document : undefined;
const pleaseSave = 'Please save your changes before executing \'OpenShift: Delete\' command.';
let message: string;

if (!document
|| !(document.fileName.endsWith('.yaml') || document.fileName.endsWith('.json'))) {
message =
'\'OpenShift: Delete\' command requires a .yaml or a .json file opened in editor.';
}

if (!message && document.isUntitled) {
message = pleaseSave;
}

if (!message && document.isDirty) {
const save = 'Save';
const action = await window.showInformationMessage('Editor has unsaved changes.', save);
if (action !== save) {
message = pleaseSave;
} else {
await document.save();
}
}

const activeProject = await YamlFileCommands.odo.getActiveProject();

if (!message && !activeProject) {
message = '\'OpenShift: Delete\' requires setting a project as active, and none is currently set.';
}

if (message) {
void window.showWarningMessage(message);
return null;
}

await OcWrapper.Instance.deleteKubernetesObjectFromFile(document.fileName);
return 'Resources were successfully deleted.';
}

}
7 changes: 7 additions & 0 deletions test/integration/ocWrapper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,13 @@ suite('./oc/ocWrapper.ts', function () {
const deployments = await Oc.Instance.getKubernetesObjects('Deployment');
expect(deployments).to.have.length(0);
});

test('deleteKubernetesObjectFromFile()', async function() {
await Oc.Instance.createKubernetesObjectFromFile(yamlFile);
await Oc.Instance.deleteKubernetesObjectFromFile(yamlFile);
const deployments = await Oc.Instance.getKubernetesObjects('Deployment');
expect(deployments).to.have.length(0);
});
});

test('getConsoleInfo()', async function() {
Expand Down

0 comments on commit 358bfee

Please sign in to comment.