From 5b09863e8a455f6da69f6b68e3cbbc1c33cafb72 Mon Sep 17 00:00:00 2001 From: Kamesh Sampath Date: Wed, 4 Jul 2018 02:51:22 +0530 Subject: [PATCH] Allow switching namespace via the command palette (#270) --- package.json | 3 ++- src/extension.ts | 28 ++++++++++++++++++---------- src/kubeNamespace.ts | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 11 deletions(-) create mode 100644 src/kubeNamespace.ts diff --git a/package.json b/package.json index 868d8c4d5..9a20dfb94 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "onCommand:extension.vsKubernetesPortForward", "onCommand:extension.vsKubernetesDeleteFile", "onCommand:extension.vsKubernetesAddFile", + "onCommand:extension.vsKubernetesUseNamespace", "onCommand:extension.helmTemplate", "onCommand:extension.helmTemplatePreview", "onCommand:extension.helmLint", @@ -418,7 +419,7 @@ }, { "command": "extension.vsKubernetesUseNamespace", - "when": "view == extension.vsKubernetesExplorer" + "when": "" }, { "command": "extension.vsKubernetesCopy", diff --git a/src/extension.ts b/src/extension.ts index efffd83b8..006c2ca88 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -15,6 +15,7 @@ import * as dockerfileParse from 'dockerfile-parse'; import * as tmp from 'tmp'; import * as uuid from 'uuid'; import * as clipboard from 'clipboardy'; +import { pullAll } from 'lodash'; // Internal dependencies import { host } from './host'; @@ -25,6 +26,7 @@ import * as configmaps from './configMap'; import * as configureFromCluster from './configurefromcluster'; import * as createCluster from './createcluster'; import * as kuberesources from './kuberesources'; +import { useNamespaceKubernetes } from './kubeNamespace'; import * as docker from './docker'; import { kubeChannel } from './kubeChannel'; import * as kubeconfig from './kubeconfig'; @@ -147,7 +149,7 @@ export async function activate(context): Promise { registerCommand('extension.vsKubernetesUseContext', useContextKubernetes), registerCommand('extension.vsKubernetesClusterInfo', clusterInfoKubernetes), registerCommand('extension.vsKubernetesDeleteContext', deleteContextKubernetes), - registerCommand('extension.vsKubernetesUseNamespace', useNamespaceKubernetes), + registerCommand('extension.vsKubernetesUseNamespace', () => { useNamespaceKubernetes(this, kubectl); } ), registerCommand('extension.vsKubernetesDashboard', () => { dashboardKubernetes(kubectl); }), registerCommand('extension.vsMinikubeStop', stopMinikube), registerCommand('extension.vsMinikubeStart', startMinikube), @@ -899,8 +901,14 @@ export function findKindNameOrPrompt(resourceKinds: kuberesources.ResourceKind[] } } -function promptKindName(resourceKinds: kuberesources.ResourceKind[], descriptionVerb, opts, handler) { - vscode.window.showInputBox({ prompt: "What resource do you want to " + descriptionVerb + "?", placeHolder: 'Empty string to be prompted' }).then((resource) => { +export function promptKindName(resourceKinds: kuberesources.ResourceKind[], descriptionVerb, opts, handler) { + let placeHolder: string = 'Empty string to be prompted'; + let prompt: string = "What resource do you want to " + descriptionVerb + "?"; + if (opts) { + placeHolder = opts.placeHolder || placeHolder; + prompt = opts.prompt || prompt; + } + vscode.window.showInputBox({ prompt, placeHolder}).then((resource) => { if (resource === '') { quickPickKindName(resourceKinds, opts, handler); } else if (resource === undefined) { @@ -931,11 +939,17 @@ function quickPickKindNameFromKind(resourceKind: kuberesources.ResourceKind, opt vscode.window.showErrorMessage(stderr); return; } + let names = parseNamesFromKubectlLines(stdout); if (names.length === 0) { vscode.window.showInformationMessage("No resources of type " + resourceKind.displayName + " in cluster"); return; } + + if (opts) { + names = pullAll(names, opts.filterNames) || names; + } + if (opts && opts.nameOptional) { names.push('(all)'); vscode.window.showQuickPick(names).then((name) => { @@ -1311,7 +1325,7 @@ async function syncKubernetes(): Promise { } } -async function refreshExplorer() { +export async function refreshExplorer() { await vscode.commands.executeCommand("extension.vsKubernetesRefreshExplorer"); } @@ -1736,12 +1750,6 @@ async function deleteContextKubernetes(explorerNode: explorer.KubernetesObject) } } -async function useNamespaceKubernetes(explorerNode: explorer.KubernetesObject) { - if (await kubectlUtils.switchNamespace(kubectl, explorerNode.id)) { - refreshExplorer(); - } -} - function copyKubernetes(explorerNode: explorer.KubernetesObject) { clipboard.writeSync(explorerNode.id); } diff --git a/src/kubeNamespace.ts b/src/kubeNamespace.ts new file mode 100644 index 000000000..a516e84bc --- /dev/null +++ b/src/kubeNamespace.ts @@ -0,0 +1,38 @@ +import { refreshExplorer, promptKindName } from './extension'; +import * as kubectlUtils from './kubectlUtils'; +import * as kuberesources from './kuberesources'; +import * as explorer from './explorer'; +import { Kubectl } from './kubectl'; + +export async function useNamespaceKubernetes(explorerNode: explorer.KubernetesObject, kubectl: Kubectl) { + if (explorerNode) { + if (await kubectlUtils.switchNamespace(kubectl, explorerNode.id)) { + refreshExplorer(); + return; + } + } else { + const currentNS = await kubectlUtils.currentNamespace(kubectl); + promptKindName([kuberesources.allKinds.namespace], undefined, + { + prompt: 'What namespace do you want to use?', + placeHolder: 'Enter the namespace to switch to or press enter to select from available list', + filterNames: [currentNS] + }, + async (resource) => { + if (resource) { + let toSwitchNamespace = resource; + // resource will be of format /, when picked up from the quickpick + if (toSwitchNamespace.lastIndexOf('/') !== -1) { + toSwitchNamespace = toSwitchNamespace.substring(toSwitchNamespace.lastIndexOf('/') + 1); + } + // Switch if an only if the currentNS and toSwitchNamespace are different + if (toSwitchNamespace && currentNS !== toSwitchNamespace) { + const promiseSwitchNS = await kubectlUtils.switchNamespace(kubectl, toSwitchNamespace); + if (promiseSwitchNS) { + refreshExplorer(); + } + } + } + }); + } +}