Skip to content

Commit

Permalink
Live update for all flux types and UI fixes (#479)
Browse files Browse the repository at this point in the history
* status bar for loading stuff

* live update for all flux types

* treeview icons fixes

* submenus

* kubectl context commands
  • Loading branch information
juozasg authored Sep 12, 2023
1 parent 8b08d1a commit aa35763
Show file tree
Hide file tree
Showing 14 changed files with 172 additions and 52 deletions.
56 changes: 50 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -156,14 +156,28 @@
},
{
"command": "gitops.views.createGitRepository",
"title": "Create GitRepository from Path",
"title": "Create Source from Path",
"category": "GitOps"
},
{
"command": "gitops.createKustomization",
"title": "Create Kustomization from Path",
"icon": "$(add)",
"enablement": "!gitops:clusterUnreachable && !gitops:currentClusterGitOpsNotEnabled",
"category": "GitOps"
},
{
"command": "gitops.kubectlApplyPath",
"title": "Apply (kubectl apply -f)",
"category": "GitOps"
},
{
"command": "gitops.kubectlDeletePath",
"title": "Delete (kubectl delete -f)",
"category": "GitOps"
},
{
"command": "gitops.kubectlApplyKustomization",
"title": "Apply Kustomization Directory (kubectl apply -k)",
"category": "GitOps"
},
{
Expand Down Expand Up @@ -322,6 +336,12 @@
"when": "gitops:currentClusterGitOpsNotEnabled && !gitops:clusterUnreachable"
}
],
"submenus": [
{
"id": "gitops.explorer",
"label": "GitOps"
}
],
"menus": {
"view/title": [
{
Expand Down Expand Up @@ -471,17 +491,41 @@
"when": "view == gitops.views.templates"
}
],
"explorer/context": [
"gitops.explorer": [
{
"command": "gitops.views.createGitRepository"
"command": "gitops.kubectlApplyPath",
"group": "1"
},
{
"command": "gitops.flux.reconcileRepository"
"command": "gitops.kubectlDeletePath",
"group": "1"
},
{
"command": "gitops.createKustomization"
"command": "gitops.kubectlApplyKustomization",
"group": "1",
"when": "explorerResourceIsFolder"
},
{
"command": "gitops.views.createGitRepository",
"group": "2"
},
{
"command": "gitops.flux.reconcileRepository",
"when": "explorerResourceIsFolder",
"group": "2"
},
{
"command": "gitops.createKustomization",
"group": "2"

}
],
"explorer/context": [
{
"submenu": "gitops.explorer"
}
],

"commandPalette": [
{
"command": "gitops.editor.openResource",
Expand Down
12 changes: 9 additions & 3 deletions src/commands/commands.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { commands, Disposable, ExtensionContext, Uri, window } from 'vscode';

import { showOutputChannel } from 'cli/shell/output';
import { refreshAllTreeViewsCommand, refreshResourcesTreeViewsCommand } from 'commands/refreshTreeViews';
import { telemetry } from 'extension';
import { CommandId } from 'types/extensionIds';
import { TelemetryError } from 'types/telemetryEventNames';
import { refreshAllTreeViewsCommand, refreshResourcesTreeViewsCommand } from 'commands/refreshTreeViews';
import { addKustomization } from './addKustomization';
import { addSource } from './addSource';
import { copyResourceName } from './copyResourceName';
Expand All @@ -14,13 +14,15 @@ import { createKustomizationForPath } from './createKustomizationForPath';
import { deleteSource } from './deleteSource';
import { deleteWorkload } from './deleteWorkload';
import { fluxDisableGitOps, fluxEnableGitOps } from './enableDisableGitOps';
import { expandAllSources, expandAllWorkloads } from './expandAll';
import { fluxCheck } from './fluxCheck';
import { checkFluxPrerequisites } from './fluxCheckPrerequisites';
import { fluxReconcileRepositoryForPath } from './fluxReconcileGitRepositoryForPath';
import { fluxReconcileSourceCommand } from './fluxReconcileSource';
import { fluxReconcileWorkload, fluxReconcileWorkloadWithSource } from './fluxReconcileWorkload';
import { installFluxCli } from './installFluxCli';
import { openResource, openKubeconfig } from './openResource';
import { kubectlApplyKustomization, kubectlApplyPath, kubectlDeletePath } from './kubectlApply';
import { openKubeconfig, openResource } from './openResource';
import { pullGitRepository } from './pullGitRepository';
import { resume } from './resume';
import { setClusterProvider } from './setClusterProvider';
Expand All @@ -32,7 +34,6 @@ import { showNewUserGuide } from './showNewUserGuide';
import { showWorkloadsHelpMessage } from './showWorkloadsHelpMessage';
import { suspend } from './suspend';
import { trace } from './trace';
import { expandAllSources, expandAllWorkloads } from './expandAll';


let _context: ExtensionContext;
Expand Down Expand Up @@ -76,6 +77,11 @@ export function registerCommands(context: ExtensionContext) {
registerCommand(CommandId.CopyResourceName, copyResourceName);
registerCommand(CommandId.AddSource, addSource);
registerCommand(CommandId.AddKustomization, addKustomization);
registerCommand(CommandId.KubectlApplyPath, kubectlApplyPath);
registerCommand(CommandId.KubectlDeletePath, kubectlDeletePath);
registerCommand(CommandId.KubectlApplyKustomization, kubectlApplyKustomization);


registerCommand(CommandId.ExpandAllSources, expandAllSources);
registerCommand(CommandId.ExpandAllWorkloads, expandAllWorkloads);

Expand Down
19 changes: 19 additions & 0 deletions src/commands/kubectlApply.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as shell from 'cli/shell/exec';
import { Uri } from 'vscode';

export async function kubectlApplyPath(uri?: Uri) {
if(uri) {
return await shell.execWithOutput(`kubectl apply -f ${uri.fsPath}`);
}
}
export async function kubectlDeletePath(uri?: Uri) {
if(uri) {
return await shell.execWithOutput(`kubectl delete -f ${uri.fsPath}`);
}
}

export async function kubectlApplyKustomization(uri?: Uri) {
if(uri) {
return await shell.execWithOutput(`kubectl apply -k ${uri.fsPath}`);
}
}
5 changes: 5 additions & 0 deletions src/types/extensionIds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ export const enum CommandId {
AddSource = 'gitops.addSource',
AddKustomization = 'gitops.addKustomization',

KubectlApplyPath = 'gitops.kubectlApplyPath',
KubectlDeletePath = 'gitops.kubectlDeletePath',
KubectlApplyKustomization = 'gitops.kubectlApplyKustomization',


// editor
EditorOpenResource = 'gitops.editor.openResource',
EditorOpenKubeconfig = 'gitops.editor.openKubeconfig',
Expand Down
8 changes: 4 additions & 4 deletions src/types/kubernetes/kubernetesTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,23 @@ export type Pod = Required<k8s.V1Pod> & {
* Defines supported Kubernetes object kinds.
*/
export const enum Kind {
List = 'List',
Bucket = 'Bucket',
GitRepository = 'GitRepository',
OCIRepository = 'OCIRepository',
HelmRepository = 'HelmRepository',
HelmRelease = 'HelmRelease',
Kustomization = 'Kustomization',
Deployment = 'Deployment',
GitOpsTemplate = 'GitOpsTemplate',

Namespace = 'Namespace',
Deployment = 'Deployment',
Node = 'Node',
Pod = 'Pod',

ConfigMap = 'ConfigMap',

GitOpsTemplate = 'GitOpsTemplate',
}


const fullKinds: Record<string, string> = {
Bucket: 'Buckets.source.toolkit.fluxcd.io',
GitRepository: 'GitRepositories.source.toolkit.fluxcd.io',
Expand Down
9 changes: 1 addition & 8 deletions src/ui/statusBar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,21 @@ class StatusBar {
private statusBarItemName = 'gitops';

private numberOfLoadingTreeViews = 0;
private loadingWasHidden = false;

constructor() {
this.statusBarItem = window.createStatusBarItem(
this.statusBarItemName,
StatusBarAlignment.Left,
-1e10,// align to the right
);
this.statusBarItem.text = '$(sync~spin) GitOps: Initializing Tree Views';
this.statusBarItem.text = '$(sync~spin) GitOps: Loading Resources';
}

/**
* Show initialization message in status bar
* (only at the extension initialization (once))
*/
startLoadingTree(): void {
if (this.loadingWasHidden) {
return;
}

this.numberOfLoadingTreeViews++;
this.statusBarItem.show();
}
Expand All @@ -38,9 +33,7 @@ class StatusBar {
this.numberOfLoadingTreeViews--;

if (this.numberOfLoadingTreeViews === 0) {
this.loadingWasHidden = true;
this.statusBarItem.hide();
this.statusBarItem.dispose();
}
}

Expand Down
28 changes: 19 additions & 9 deletions src/ui/treeviews/dataProviders/kubernetesObjectDataProvider.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { getNamespace } from 'cli/kubernetes/kubectlGetNamespace';
import { currentContextData } from 'data/contextData';
import { GitRepository } from 'types/flux/gitRepository';
import { KubernetesObject } from 'types/kubernetes/kubernetesTypes';
import { groupNodesByNamespace, sortNodes } from 'utils/treeNodeUtils';
import { makeTreeNode } from '../nodes/makeTreeNode';
import { NamespaceNode } from '../nodes/namespaceNode';
import { GitRepositoryNode } from '../nodes/source/gitRepositoryNode';
import { TreeNode } from '../nodes/treeNode';
import { AsyncDataProvider } from './asyncDataProvider';

Expand Down Expand Up @@ -42,24 +41,31 @@ export abstract class KubernetesObjectDataProvider extends AsyncDataProvider {
namespaceNode = new NamespaceNode(ns);
this.nodes?.push(namespaceNode);
sortNodes(this.nodes);
namespaceNode.expand();
this.redraw();
setTimeout(() => {
namespaceNode!.updateLabel();
namespaceNode!.expand();
this.redraw(namespaceNode);
}, 0);
}


if(namespaceNode.findChildByResource(object)) {
this.update(object);
namespaceNode.updateLabel();
this.redraw(namespaceNode);
this.redraw();
return;
}

const resourceNode = makeTreeNode(object);
if(!resourceNode) {
return;
}

const resourceNode = new GitRepositoryNode(object as GitRepository);
namespaceNode.addChild(resourceNode);
sortNodes(namespaceNode.children);

namespaceNode.updateLabel();
this.redraw(namespaceNode);
this.redraw();
}

public update(object: KubernetesObject) {
Expand All @@ -72,8 +78,12 @@ export abstract class KubernetesObjectDataProvider extends AsyncDataProvider {
if(node && node.resource) {
node.resource = object;
node.updateStatus();
namespaceNode.updateLabel();
this.redraw(namespaceNode);

setTimeout(() => {
namespaceNode!.updateLabel();
this.redraw(namespaceNode);
}, 0);

}
}

Expand Down
2 changes: 0 additions & 2 deletions src/ui/treeviews/nodes/cluster/clusterNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,6 @@ export class ClusterNode extends TreeNode {

this.children = [];
if (this.isGitOpsEnabled) {
// load flux system deployments
this.expand();
revealClusterNode(this, {
expand: false,
});
Expand Down
41 changes: 41 additions & 0 deletions src/ui/treeviews/nodes/makeTreeNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { KubernetesObject } from '@kubernetes/client-node';
import { Kind } from 'types/kubernetes/kubernetesTypes';
import { AnyResourceNode } from './anyResourceNode';
import { GitOpsTemplateNode } from './gitOpsTemplateNode';
import { NamespaceNode } from './namespaceNode';
import { BucketNode } from './source/bucketNode';
import { GitRepositoryNode } from './source/gitRepositoryNode';
import { HelmRepositoryNode } from './source/helmRepositoryNode';
import { OCIRepositoryNode } from './source/ociRepositoryNode';
import { TreeNode } from './treeNode';
import { HelmReleaseNode } from './workload/helmReleaseNode';
import { KustomizationNode } from './workload/kustomizationNode';

// eslint-disable-next-line @typescript-eslint/ban-types
const nodeConstructors = {
'Bucket': BucketNode,
'GitRepository': GitRepositoryNode,
'OCIRepository': OCIRepositoryNode,
'HelmRepository': HelmRepositoryNode,
'HelmRelease': HelmReleaseNode,
'Kustomization': KustomizationNode,
'GitOpsTemplate': GitOpsTemplateNode,

'Namespace': NamespaceNode,

'Deployment': AnyResourceNode,
'Node': AnyResourceNode,
'Pod': AnyResourceNode,
'ConfigMap': AnyResourceNode,
};

export function makeTreeNode(object: KubernetesObject): TreeNode | undefined {
if(!object.kind) {
return;
}

const constructor = nodeConstructors[object.kind as Kind];
if(constructor) {
return new constructor(object as any);
}
}
Loading

0 comments on commit aa35763

Please sign in to comment.