Skip to content

Commit

Permalink
Migrate Kubernetes extension commands redhat-developer#3990
Browse files Browse the repository at this point in the history
Fixes: redhat-developer#3990

Signed-off-by: Victor Rubezhny <vrubezhny@redhat.com>
  • Loading branch information
vrubezhny committed May 8, 2024
1 parent 49d16c5 commit ea361cf
Show file tree
Hide file tree
Showing 13 changed files with 320 additions and 52 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ jobs:
run: npm run test
- name: Package
run: |
jq --tab '.extensionDependencies += [ "ms-kubernetes-tools.vscode-kubernetes-tools" ]' package.json > package.json.new
mv package.json.new package.json
node ./out/build/update-readme.js
declare -A targets
targets["win32-x64"]=win32
Expand Down
1 change: 0 additions & 1 deletion README.commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ When installing the extension directly from the VSCode marketplace all the depen

* [Red Hat Authentication](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-redhat-account)
* [YAML Extension](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml)
* [Kubernetes Extension](https://marketplace.visualstudio.com/items?itemName=ms-kubernetes-tools.vscode-kubernetes-tools)

### CLI Tools

Expand Down
25 changes: 12 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,6 @@
"onCommand:openshift.explorer.reportIssue",
"onCommand:openshift.explorer.switchContext",
"onCommand:clusters.openshift.project.openConsole",
"onCommand:clusters.openshift.useProject",
"onCommand:clusters.openshift.deploy",
"onCommand:clusters.openshift.build.start",
"onCommand:clusters.openshift.build.showLog",
Expand All @@ -255,7 +254,8 @@
"onCommand:openshift.component.deleteConfigurationFiles",
"onCommand:openshift.component.deleteSourceFolder",
"onWalkthrough:openshiftWalkthrough",
"onWalkthrough:serverlessFunctionWalkthrough"
"onWalkthrough:serverlessFunctionWalkthrough",
"onFileSystem:k8smsx"
],
"contributes": {
"configurationDefaults": {
Expand Down Expand Up @@ -607,11 +607,6 @@
"title": "Debug Component",
"category": "OpenShift"
},
{
"command": "clusters.openshift.useProject",
"title": "Use Project",
"category": "OpenShift"
},
{
"command": "clusters.openshift.project.openConsole",
"title": "Open in Console",
Expand Down Expand Up @@ -1872,10 +1867,6 @@
"when": "view == openshiftComponentsView && viewItem =~ /openshift\\.component.*\\.dev-run.*/",
"group": "c3@4"
},
{
"command": "clusters.openshift.useProject",
"when": "viewItem =~ /\\.openshift\\.inactiveProject/i"
},
{
"command": "clusters.openshift.project.openConsole",
"when": "view == extension.vsKubernetesExplorer && viewItem =~ /vsKubernetes\\.resource\\.project*/i"
Expand Down Expand Up @@ -2243,6 +2234,15 @@
"default": 0,
"description": "Output verbosity level (value between 0 and 9) for OpenShift Create, and Dev commands in output channel and integrated terminal."
},
"openshiftToolkit.outputFormat": {
"enum": [
"json",
"yaml"
],
"type": "string",
"default": "yaml",
"description": "Output format for Kubernetes specs. One of 'json' or 'yaml' (default)."
},
"openshiftToolkit.searchForToolsInPath": {
"type": "boolean",
"default": false,
Expand Down Expand Up @@ -2311,8 +2311,7 @@
]
},
"extensionDependencies": [
"redhat.vscode-redhat-account",
"ms-kubernetes-tools.vscode-kubernetes-tools"
"redhat.vscode-redhat-account"
],
"__metadata": {
"id": "8fea1f1f-b45c-4eea-b479-3a92c6e697d3",
Expand Down
34 changes: 4 additions & 30 deletions src/explorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { CustomResourceDefinitionStub } from './webview/common/createServiceType
import { OpenShiftTerminalManager } from './webview/openshift-terminal/openShiftTerminal';
import { LoginUtil } from './util/loginUtil';
import { PortForward } from './port-forward';
import { getOutputFormat, kubefsUri } from './k8s/vfs/kuberesources.virtualfs';

type ExplorerItem = KubernetesObject | Helm.HelmRelease | Context | TreeItem | OpenShiftObject | HelmRepo;

Expand Down Expand Up @@ -528,8 +529,8 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
* @param value deployment name
*/
loadKubernetesCore(namespace: string | null, value: string) {
const outputFormat = this.getOutputFormat();
const uri = this.kubefsUri(namespace, value, outputFormat);
const outputFormat = getOutputFormat();
const uri = kubefsUri(namespace, value, outputFormat);

const query = this.getComparableQuery(uri);
const openUri = workspace.textDocuments.map((doc) => doc.uri)
Expand All @@ -551,33 +552,6 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos
(err) => window.showErrorMessage(`Error loading document: ${err}`));
}

/**
* get output format from vs-kubernetes.outputFormat
* default yaml
*
* @returns output format
*/
getOutputFormat(): string {
if (workspace.getConfiguration('vs-kubernetes').has('vs-kubernetes.outputFormat')) {
return workspace.getConfiguration('vs-kubernetes').get['vs-kubernetes.outputFormat'] as string;
}
return 'yaml'
}

kubefsUri(namespace: string | null | undefined, value: string, outputFormat: string, action?: string): Uri {
const K8S_RESOURCE_SCHEME = 'k8smsx';
const K8S_RESOURCE_SCHEME_READONLY = 'k8smsxro';
const KUBECTL_RESOURCE_AUTHORITY = 'loadkubernetescore';
const KUBECTL_DESCRIBE_AUTHORITY = 'kubernetesdescribe';
const docname = `${value.replace('/', '-')}${outputFormat && outputFormat !== '' ? `.${outputFormat}` : ''}`;
const nonce = new Date().getTime();
const nsquery = namespace ? `ns=${namespace}&` : '';
const scheme = action === 'describe' ? K8S_RESOURCE_SCHEME_READONLY : K8S_RESOURCE_SCHEME;
const authority = action === 'describe' ? KUBECTL_DESCRIBE_AUTHORITY : KUBECTL_RESOURCE_AUTHORITY;
const uri = `${scheme}://${authority}/${docname}?${nsquery}value=${value}&_=${nonce}`;
return Uri.parse(uri);
}

/*
* Returns the query string of the specified Uri without "nonce" param,
* so the query strings can be compared.
Expand Down Expand Up @@ -640,7 +614,7 @@ export class OpenShiftExplorer implements TreeDataProvider<ExplorerItem>, Dispos

@vsCommand('openshift.resource.openInConsole')
public static openInConsole(component: KubernetesObject) {
void commands.executeCommand('extension.vsKubernetesLoad', { namespace: component.metadata.namespace, kindName: `${component.kind}/${component.metadata.name}` });
void commands.executeCommand('openshift.resource.load', { namespace: component.metadata.namespace, kindName: `${component.kind}/${component.metadata.name}` });
}

@vsCommand('openshift.explorer.reportIssue')
Expand Down
17 changes: 14 additions & 3 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { registerYamlHandlers } from './yaml/yamlDocumentFeatures';

import fsx = require('fs-extra');
import { Oc } from './oc/ocWrapper';
import { K8S_RESOURCE_SCHEME, K8S_RESOURCE_SCHEME_READONLY, KubernetesResourceVirtualFileSystemProvider } from './k8s/vfs/kuberesources.virtualfs';

// eslint-disable-next-line @typescript-eslint/no-empty-function
// this method is called when your extension is deactivated
Expand Down Expand Up @@ -76,6 +77,12 @@ export async function activate(extensionContext: ExtensionContext): Promise<unkn
Cluster.extensionContext = extensionContext;
TokenStore.extensionContext = extensionContext;

// Temporarily loaded resource providers
const resourceDocProvider = new KubernetesResourceVirtualFileSystemProvider();

// Link from resources to referenced resources
// const resourceLinkProvider = new KubernetesResourceLinkProvider();

// pick kube config in case multiple are configured
await setKubeConfig();

Expand Down Expand Up @@ -104,9 +111,6 @@ export async function activate(extensionContext: ExtensionContext): Promise<unkn
'./feedback',
'./deployment'
)),
commands.registerCommand('clusters.openshift.useProject', (context) =>
commands.executeCommand('extension.vsKubernetesUseNamespace', context),
),
crcStatusItem,
activeNamespaceStatusBarItem,
activeContextStatusBarItem,
Expand All @@ -119,6 +123,13 @@ export async function activate(extensionContext: ExtensionContext): Promise<unkn
setupWorkspaceDevfileContext(),
window.registerWebviewViewProvider('openShiftTerminalView', OpenShiftTerminalManager.getInstance(), { webviewOptions: { retainContextWhenHidden: true, } }),
...registerYamlHandlers(),
// Temporarily loaded resource providers
workspace.registerFileSystemProvider(K8S_RESOURCE_SCHEME, resourceDocProvider, { /* TODO: case sensitive? */ }),
workspace.registerFileSystemProvider(K8S_RESOURCE_SCHEME_READONLY, resourceDocProvider, { isReadonly: true }),

// Link from resources to referenced resources
// languages.registerDocumentLinkProvider({ scheme: K8S_RESOURCE_SCHEME }, resourceLinkProvider),

];
disposable.forEach((value) => extensionContext.subscriptions.push(value));

Expand Down
33 changes: 33 additions & 0 deletions src/helm/helm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Copyright (c) Red Hat, Inc. All rights reserved.
* Licensed under the MIT License. See LICENSE file in the project root for license information.
*-----------------------------------------------------------------------------------------------*/
import { CommandText } from '../base/command';
import { CliChannel } from '../cli';
import { CliExitData } from '../util/childProcessUtil';
import { HelmRepo } from './helmChartType';
Expand Down Expand Up @@ -108,3 +109,35 @@ export function ascRepoName(oldRepo: HelmRepo, newRepo: HelmRepo) {
}
return oldRepo.name.localeCompare(newRepo.name);
}

// This file contains utilities for executing command line tools, notably Helm.

export enum HelmSyntaxVersion {
Unknown = 1,
V2 = 2,
V3 = 3,
}

let cachedVersion: HelmSyntaxVersion | undefined = undefined;

export async function helmSyntaxVersion(): Promise<HelmSyntaxVersion> {
if (cachedVersion === undefined) {
const srHelm2 = await CliChannel.getInstance().executeTool(new CommandText('helm version --short -c'));
if (CliExitData.failed(srHelm2)) {
// failed to run Helm; do not cache result
return HelmSyntaxVersion.Unknown;
}

if (srHelm2.stdout.indexOf('v2') >= 0) {
cachedVersion = HelmSyntaxVersion.V2;
} else {
const srHelm3 = await CliChannel.getInstance().executeTool(new CommandText('helm version --short'));
if (!CliExitData.failed(srHelm3) && srHelm3.stdout.indexOf('v3') >= 0) {
cachedVersion = HelmSyntaxVersion.V3;
} else {
return HelmSyntaxVersion.Unknown;
}
}
}
return cachedVersion;
}
2 changes: 1 addition & 1 deletion src/k8s/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export class Node implements ClusterExplorerV1.Node, ClusterExplorerV1.ClusterEx
item.contextValue = `openShift.resource.${this.node}`;
item.command = {
arguments: [this],
command: 'extension.vsKubernetesLoad',
command: 'openshift.resource.load',
title: 'Load'
};
return item;
Expand Down
35 changes: 35 additions & 0 deletions src/k8s/vfs/errorable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*-----------------------------------------------------------------------------------------------
* Copyright (c) Red Hat, Inc. All rights reserved.
* Licensed under the MIT License. See LICENSE file in the project root for license information.
*-----------------------------------------------------------------------------------------------*/

export interface Succeeded<T> {
readonly succeeded: true;
readonly result: T;
}

export interface Failed {
readonly succeeded: false;
readonly error: string[];
}

export type Errorable<T> = Succeeded<T> | Failed;

export function succeeded<T>(e: Errorable<T>): e is Succeeded<T> {
return e.succeeded;
}

export function failed<T>(e: Errorable<T>): e is Failed {
return !e.succeeded;
}

// eslint-disable-next-line @typescript-eslint/no-namespace
export namespace Errorable {
export function succeeded<T>(e: Errorable<T>): e is Succeeded<T> {
return e.succeeded;
}

export function failed<T>(e: Errorable<T>): e is Failed {
return !e.succeeded;
}
}
Loading

0 comments on commit ea361cf

Please sign in to comment.