Skip to content

Commit

Permalink
Create Helm templates from resource manifests (vscode-kubernetes-tool…
Browse files Browse the repository at this point in the history
  • Loading branch information
itowlson authored Aug 13, 2018
1 parent ada3de2 commit 9971e29
Show file tree
Hide file tree
Showing 11 changed files with 695 additions and 21 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,8 @@ Minikube tools to be installed and available on your PATH.
* `Helm: Insert Dependency` - Insert a dependency YAML fragment
* `Helm: Dependency Update` - Update a chart's dependencies
* `Helm: Package` - Package a chart directory into a chart archive
* `Helm: Convert to Template` - Create a template based on an existing resource or manifest
* `Helm: Convert to Template Parameter` - Convert a fixed value in a template to a parameter in the `values.yaml` file
* Code lenses for:
* requirements.yaml (Add and update dependencies)
* Right-click on a chart .tgz file, and choose inspect chart to preview all configurable chart values.
Expand Down
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 40 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@
"onCommand:extension.helmFetch",
"onCommand:extension.helmInstall",
"onCommand:extension.helmDependencies",
"onCommand:extension.helmConvertToTemplate",
"onCommand:extension.helmParameterise",
"onCommand:extension.draftVersion",
"onCommand:extension.draftCreate",
"onCommand:extension.draftUp",
Expand Down Expand Up @@ -176,6 +178,11 @@
"when": "",
"command": "extension.helmInspectValues",
"group": "2_helm@98"
},
{
"when": "",
"command": "extension.helmConvertToTemplate",
"group": "2_helm@98"
}
],
"view/title": [
Expand Down Expand Up @@ -324,6 +331,11 @@
"group": "3",
"when": "view == extension.vsKubernetesExplorer && viewItem == vsKubernetes.resource"
},
{
"command": "extension.helmConvertToTemplate",
"group": "2",
"when": "view == extension.vsKubernetesExplorer && viewItem == vsKubernetes.resource"
},
{
"command": "extension.vsKubernetesLoad",
"group": "0",
Expand Down Expand Up @@ -369,6 +381,11 @@
"group": "3",
"when": "view == extension.vsKubernetesExplorer && viewItem == vsKubernetes.resource.pod"
},
{
"command": "extension.helmConvertToTemplate",
"group": "2",
"when": "view == extension.vsKubernetesExplorer && viewItem == vsKubernetes.resource.pod"
},
{
"command": "extension.vsKubernetesShowLogs",
"group": "3",
Expand Down Expand Up @@ -404,6 +421,11 @@
"group": "3",
"when": "view == extension.vsKubernetesExplorer && viewItem == vsKubernetes.resource.configmap"
},
{
"command": "extension.helmConvertToTemplate",
"group": "2",
"when": "view == extension.vsKubernetesExplorer && viewItem == vsKubernetes.resource.configmap"
},
{
"command": "extension.vsKubernetesAddFile",
"group": "3",
Expand All @@ -424,6 +446,11 @@
"group": "2@1",
"when": "view == extension.vsKubernetesExplorer && viewItem == vsKubernetes.resource.secret"
},
{
"command": "extension.helmConvertToTemplate",
"group": "2",
"when": "view == extension.vsKubernetesExplorer && viewItem == vsKubernetes.resource.secret"
},
{
"command": "extension.vsKubernetesDelete",
"group": "2@2",
Expand Down Expand Up @@ -827,6 +854,18 @@
"description": "Create a new Helm Chart",
"category": "Helm"
},
{
"command": "extension.helmConvertToTemplate",
"title": "Convert to Template",
"description": "Convert this manifest to a Helm template",
"category": "Helm"
},
{
"command": "extension.helmParameterise",
"title": "Convert to Template Parameter",
"description": "Convert this value to a Helm template parameter",
"category": "Helm"
},
{
"command": "extension.helmGet",
"title": "Get Release",
Expand Down Expand Up @@ -1035,6 +1074,7 @@
"vscode-debugprotocol": "1.27.0",
"vscode-extension-telemetry": "^0.0.6",
"vscode-uri": "^1.0.1",
"yaml-ast-parser": "^0.0.40",
"yamljs": "0.2.10"
},
"devDependencies": {
Expand Down
10 changes: 10 additions & 0 deletions src/explorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Host } from './host';
import * as kuberesources from './kuberesources';
import { failed } from './errorable';
import * as helmexec from './helm.exec';
import { K8S_RESOURCE_SCHEME, KUBECTL_RESOURCE_AUTHORITY, kubefsUri } from './kuberesources.virtualfs';

const KUBERNETES_CLUSTER = "vsKubernetes.cluster";
const MINIKUBE_CLUSTER = "vsKubernetes.minikubeCluster";
Expand Down Expand Up @@ -49,9 +50,14 @@ export interface KubernetesObject {
export interface ResourceNode {
readonly id: string;
readonly resourceId: string;
uri(outputFormat: string): vscode.Uri;
namespace: string | null;
}

export function isKubernetesExplorerResourceNode(obj: any): obj is ResourceNode {
return obj && obj.id && obj.resourceId;
}

export class KubernetesExplorer implements vscode.TreeDataProvider<KubernetesObject> {
private onDidChangeTreeDataEmitter: vscode.EventEmitter<KubernetesObject | undefined> = new vscode.EventEmitter<KubernetesObject | undefined>();
readonly onDidChangeTreeData: vscode.Event<KubernetesObject | undefined> = this.onDidChangeTreeDataEmitter.event;
Expand Down Expand Up @@ -238,6 +244,10 @@ class KubernetesResource implements KubernetesObject, ResourceNode {
return (this.metadata && this.metadata.namespace) ? this.metadata.namespace : null;
}

uri(outputFormat: string): vscode.Uri {
return kubefsUri(this.namespace, this.resourceId, outputFormat);
}

getChildren(kubectl: Kubectl, host: Host): vscode.ProviderResult<KubernetesObject[]> {
return [];
}
Expand Down
56 changes: 49 additions & 7 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import { create as minikubeCreate, CheckPresentMode as MinikubeCheckPresentMode
import * as logger from './logger';
import * as helm from './helm';
import * as helmexec from './helm.exec';
import * as helmauthoring from './helm.authoring';
import { HelmRequirementsCodeLensProvider } from './helm.requirementsCodeLens';
import { HelmTemplateHoverProvider } from './helm.hoverProvider';
import { HelmTemplatePreviewDocumentProvider, HelmInspectDocumentProvider, HelmDependencyDocumentProvider } from './helm.documentProvider';
Expand All @@ -65,9 +66,10 @@ import { KubernetesCompletionProvider } from "./yaml-support/yaml-snippet";
import { showWorkspaceFolderPick } from './hostutils';
import { DraftConfigurationProvider } from './draft/draftConfigurationProvider';
import { installHelm, installDraft, installKubectl, installMinikube } from './components/installer/installer';
import { KubernetesResourceVirtualFileSystemProvider, K8S_RESOURCE_SCHEME, KUBECTL_RESOURCE_AUTHORITY } from './kuberesources.virtualfs';
import { KubernetesResourceVirtualFileSystemProvider, K8S_RESOURCE_SCHEME, KUBECTL_RESOURCE_AUTHORITY, kubefsUri } from './kuberesources.virtualfs';
import { Container, isKubernetesResource, KubernetesCollection, Pod, KubernetesResource } from './kuberesources.objectmodel';
import { setActiveKubeconfig, getKnownKubeconfigs, addKnownKubeconfig } from './components/config/config';
import { HelmDocumentSymbolProvider } from './helm.symbolProvider';

let explainActive = false;
let swaggerSpecPromise = null;
Expand Down Expand Up @@ -119,6 +121,7 @@ export async function activate(context): Promise<extensionapi.ExtensionAPI> {
const previewProvider = new HelmTemplatePreviewDocumentProvider();
const inspectProvider = new HelmInspectDocumentProvider();
const dependenciesProvider = new HelmDependencyDocumentProvider();
const helmSymbolProvider = new HelmDocumentSymbolProvider();
const completionProvider = new HelmTemplateCompletionProvider();
const completionFilter = [
"helm",
Expand Down Expand Up @@ -188,6 +191,8 @@ export async function activate(context): Promise<extensionapi.ExtensionAPI> {
registerCommand('extension.helmFetch', helmexec.helmFetch),
registerCommand('extension.helmInstall', (o) => helmexec.helmInstall(kubectl, o)),
registerCommand('extension.helmDependencies', helmexec.helmDependencies),
registerCommand('extension.helmConvertToTemplate', helmConvertToTemplate),
registerCommand('extension.helmParameterise', helmParameterise),

// Commands - Draft
registerCommand('extension.draftVersion', execDraftVersion),
Expand All @@ -209,6 +214,9 @@ export async function activate(context): Promise<extensionapi.ExtensionAPI> {
vscode.languages.registerCompletionItemProvider(completionFilter, completionProvider),
vscode.languages.registerCompletionItemProvider('yaml', new KubernetesCompletionProvider()),

// Symbol providers
vscode.languages.registerDocumentSymbolProvider({ language: 'helm' }, helmSymbolProvider),

// Hover providers
vscode.languages.registerHoverProvider(
{ language: 'json', scheme: 'file' },
Expand Down Expand Up @@ -307,6 +315,7 @@ export async function activate(context): Promise<extensionapi.ExtensionAPI> {
context.subscriptions.push(element);
}, this);
await registerYamlSchemaSupport();

vscode.workspace.registerTextDocumentContentProvider(configmaps.uriScheme, configMapProvider);
return {
apiVersion: '0.1',
Expand Down Expand Up @@ -662,11 +671,8 @@ function loadKubernetes(explorerNode?: explorer.ResourceNode) {

function loadKubernetesCore(namespace: string | null, value: string) {
const outputFormat = vscode.workspace.getConfiguration('vs-kubernetes')['vs-kubernetes.outputFormat'];
const docname = `${value.replace('/', '-')}.${outputFormat}`;
const nonce = new Date().getTime();
const nsquery = namespace ? `ns=${namespace}&` : '';
const uri = `${K8S_RESOURCE_SCHEME}://${KUBECTL_RESOURCE_AUTHORITY}/${docname}?${nsquery}value=${value}&_=${nonce}`;
vscode.workspace.openTextDocument(vscode.Uri.parse(uri)).then((doc) => {
const uri = kubefsUri(namespace, value, outputFormat);
vscode.workspace.openTextDocument(uri).then((doc) => {
if (doc) {
vscode.window.showTextDocument(doc);
}
Expand Down Expand Up @@ -1865,4 +1871,40 @@ async function execDraftUp() {
function editorIsActive(): boolean {
// force type coercion
return (vscode.window.activeTextEditor) ? true : false;
}
}

async function helmConvertToTemplate(arg?: any) {
const workspace = await showWorkspaceFolderPick();
if (!workspace) {
return;
}
helmauthoring.convertToTemplate(fs, host, workspace.uri.fsPath, arg);
}

async function helmParameterise() {
const activeEditor = vscode.window.activeTextEditor;
if (!activeEditor) {
return;
}

const document = activeEditor.document;
if (!document) {
return;
}

const selection = activeEditor.selection;
if (!selection) {
return;
}

const convertResult = await helmauthoring.convertToParameter(fs, host, document, selection);

if (succeeded(convertResult)) {
const editor = await vscode.window.showTextDocument(convertResult.result.document);
const edit = convertResult.result.edit;
editor.revealRange(edit.range);
editor.selection = new vscode.Selection(edit.range.start, edit.range.end); // TODO: this isn't quite right because it gives us the insert-at selection not the resultant edit
} else {
vscode.window.showErrorMessage(convertResult.error[0]);
}
}
5 changes: 4 additions & 1 deletion src/fs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface FS {
unlinkAsync(path: string): Promise<void>;
existsAsync(path: string): Promise<boolean>;
openAsync(path: string, flags: string): Promise<void>;
statSync(path: string): sysfs.Stats;
}

export const fs: FS = {
Expand Down Expand Up @@ -54,5 +55,7 @@ export const fs: FS = {
resolve();
});
});
}
},

statSync: (path) => sysfs.statSync(path)
};
Loading

0 comments on commit 9971e29

Please sign in to comment.