From 1ec4bd430534f48885109eaec415d9f086ac124e Mon Sep 17 00:00:00 2001 From: Philippe Martin Date: Thu, 22 Feb 2024 21:15:49 +0100 Subject: [PATCH] Add complete object from contexts informers (#6116) * refactor: use index signature for resources counts Signed-off-by: Philippe Martin * refactor: send complete objects instead of counts Signed-off-by: Philippe Martin * test: fix badge tests Signed-off-by: Philippe Martin --- .../plugin/kubernetes-context-state.spec.ts | 44 ++++++++++++------- .../src/plugin/kubernetes-context-state.ts | 34 ++++++++++---- ...erencesKubernetesContextsRendering.spec.ts | 12 +++-- ...ferencesKubernetesContextsRendering.svelte | 4 +- ...netesCurrentContextConnectionBadge.spec.ts | 30 ++++++++----- 5 files changed, 84 insertions(+), 40 deletions(-) diff --git a/packages/main/src/plugin/kubernetes-context-state.spec.ts b/packages/main/src/plugin/kubernetes-context-state.spec.ts index 72151378bab..0005b436475 100644 --- a/packages/main/src/plugin/kubernetes-context-state.spec.ts +++ b/packages/main/src/plugin/kubernetes-context-state.spec.ts @@ -88,14 +88,14 @@ function fakeMakeInformer( case '/api/v1/namespaces/ns2/pods': return new FakeInformer(2, connectResult); case '/api/v1/namespaces/default/pods': - return new FakeInformer(9, connectResult); + return new FakeInformer(3, connectResult); case '/apis/apps/v1/namespaces/ns1/deployments': - return new FakeInformer(11, connectResult); + return new FakeInformer(4, connectResult); case '/apis/apps/v1/namespaces/ns2/deployments': - return new FakeInformer(12, connectResult); + return new FakeInformer(5, connectResult); case '/apis/apps/v1/namespaces/default/deployments': - return new FakeInformer(19, connectResult); + return new FakeInformer(6, connectResult); } return new FakeInformer(0, connectResult); } @@ -167,26 +167,34 @@ test('should send info of resources in all reachable contexts and nothing in non expectedMap.set('context1', { reachable: false, error: 'Error: connection error', - podsCount: 0, - deploymentsCount: 0, + resources: { + pods: [], + deployments: [], + }, } as ContextState); expectedMap.set('context2', { reachable: true, error: undefined, - podsCount: 9, - deploymentsCount: 19, + resources: { + pods: [{}, {}, {}], + deployments: [{}, {}, {}, {}, {}, {}], + }, } as ContextState); expectedMap.set('context2-1', { reachable: true, error: undefined, - podsCount: 1, - deploymentsCount: 11, + resources: { + pods: [{}], + deployments: [{}, {}, {}, {}], + }, } as ContextState); expectedMap.set('context2-2', { reachable: true, error: undefined, - podsCount: 2, - deploymentsCount: 12, + resources: { + pods: [{}, {}], + deployments: [{}, {}, {}, {}, {}], + }, } as ContextState); await new Promise(resolve => setTimeout(resolve, 1200)); expect(apiSenderSendMock).toHaveBeenCalledWith('kubernetes-contexts-state-update', expectedMap); @@ -232,13 +240,17 @@ test('should send info of resources in all reachable contexts and nothing in non expectedMap = new Map(); expectedMap.set('context2', { reachable: true, - podsCount: 9, - deploymentsCount: 19, + resources: { + pods: [{}, {}, {}], + deployments: [{}, {}, {}, {}, {}, {}], + }, } as ContextState); expectedMap.set('context2-1', { reachable: true, - podsCount: 1, - deploymentsCount: 11, + resources: { + pods: [{}], + deployments: [{}, {}, {}, {}], + }, } as ContextState); await new Promise(resolve => setTimeout(resolve, 1200)); expect(apiSenderSendMock).toHaveBeenLastCalledWith('kubernetes-contexts-state-update', expectedMap); diff --git a/packages/main/src/plugin/kubernetes-context-state.ts b/packages/main/src/plugin/kubernetes-context-state.ts index 5662966bef7..8ba4b03c8d8 100644 --- a/packages/main/src/plugin/kubernetes-context-state.ts +++ b/packages/main/src/plugin/kubernetes-context-state.ts @@ -39,10 +39,15 @@ interface ContextInternalState { export interface ContextState { error?: string; reachable: boolean; - podsCount: number; - deploymentsCount: number; + resources: ContextStateResources; } +type ResourceName = 'pods' | 'deployments'; + +export type ContextStateResources = { + [resourceName in ResourceName]: KubernetesObject[]; +}; + interface CreateInformerOptions { checkReachable?: boolean; onAdd?: (obj: T) => void; @@ -107,8 +112,10 @@ class ContextsStates { this.published.set(name, { error: undefined, reachable: false, - podsCount: 0, - deploymentsCount: 0, + resources: { + pods: [], + deployments: [], + }, }); } const val = this.published.get(name); @@ -193,8 +200,12 @@ export class ContextsManager { return this.createInformer(kc, context, path, listFn, { timer: this.podTimer, backoff: new Backoff(1000, 60_000, 300), - onAdd: _obj => this.setStateAndDispatch(context.name, state => state.podsCount++), - onDelete: _obj => this.setStateAndDispatch(context.name, state => state.podsCount--), + onAdd: obj => this.setStateAndDispatch(context.name, state => state.resources.pods.push(obj)), + onDelete: obj => + this.setStateAndDispatch( + context.name, + state => (state.resources.pods = state.resources.pods.filter(d => d.metadata?.uid !== obj.metadata?.uid)), + ), onReachable: reachable => this.setStateAndDispatch(context.name, state => { state.reachable = reachable; @@ -215,8 +226,15 @@ export class ContextsManager { return this.createInformer(kc, context, path, listFn, { timer: this.deploymentTimer, backoff: new Backoff(1000, 60_000, 300), - onAdd: _obj => this.setStateAndDispatch(context.name, state => state.deploymentsCount++), - onDelete: _obj => this.setStateAndDispatch(context.name, state => state.deploymentsCount--), + onAdd: obj => this.setStateAndDispatch(context.name, state => state.resources.deployments.push(obj)), + onDelete: obj => + this.setStateAndDispatch( + context.name, + state => + (state.resources.deployments = state.resources.deployments.filter( + d => d.metadata?.uid !== obj.metadata?.uid, + )), + ), }); } diff --git a/packages/renderer/src/lib/preferences/PreferencesKubernetesContextsRendering.spec.ts b/packages/renderer/src/lib/preferences/PreferencesKubernetesContextsRendering.spec.ts index 27f37c977bc..d1d709ee5aa 100644 --- a/packages/renderer/src/lib/preferences/PreferencesKubernetesContextsRendering.spec.ts +++ b/packages/renderer/src/lib/preferences/PreferencesKubernetesContextsRendering.spec.ts @@ -152,13 +152,17 @@ test('state and resources counts are displayed in contexts', () => { const state: Map = new Map(); state.set('context-name', { reachable: true, - podsCount: 1, - deploymentsCount: 2, + resources: { + pods: [{}], + deployments: [{}, {}], + }, }); state.set('context-name2', { reachable: false, - podsCount: 0, - deploymentsCount: 0, + resources: { + pods: [], + deployments: [], + }, }); vi.mocked(kubernetesContextsState).kubernetesContextsState = readable>(state); render(PreferencesKubernetesContextsRendering, {}); diff --git a/packages/renderer/src/lib/preferences/PreferencesKubernetesContextsRendering.svelte b/packages/renderer/src/lib/preferences/PreferencesKubernetesContextsRendering.svelte index bcc35229f96..aaeb8ecc012 100644 --- a/packages/renderer/src/lib/preferences/PreferencesKubernetesContextsRendering.svelte +++ b/packages/renderer/src/lib/preferences/PreferencesKubernetesContextsRendering.svelte @@ -108,13 +108,13 @@ async function handleDeleteContext(contextName: string) {
PODS
- {$kubernetesContextsState.get(context.name)?.podsCount} + {$kubernetesContextsState.get(context.name)?.resources.pods.length}
DEPLOYMENTS
- {$kubernetesContextsState.get(context.name)?.deploymentsCount} + {$kubernetesContextsState.get(context.name)?.resources.deployments.length}
diff --git a/packages/renderer/src/lib/ui/KubernetesCurrentContextConnectionBadge.spec.ts b/packages/renderer/src/lib/ui/KubernetesCurrentContextConnectionBadge.spec.ts index def42409c99..af3fa7443c6 100644 --- a/packages/renderer/src/lib/ui/KubernetesCurrentContextConnectionBadge.spec.ts +++ b/packages/renderer/src/lib/ui/KubernetesCurrentContextConnectionBadge.spec.ts @@ -62,8 +62,10 @@ test('expect badges to show as there is a context', async () => { mocks.getCurrentKubeContextState.mockReturnValue({ error: undefined, reachable: true, - deploymentsCount: 0, - podsCount: 0, + resources: { + pods: [], + deployments: [], + }, } as ContextState); // no current ContextState render(KubernetesCurrentContextConnectionBadge); @@ -76,8 +78,10 @@ test('expect badges to be green when reachable', async () => { mocks.getCurrentKubeContextState.mockReturnValue({ error: undefined, reachable: true, - deploymentsCount: 0, - podsCount: 0, + resources: { + pods: [], + deployments: [], + }, } as ContextState); // no current ContextState render(KubernetesCurrentContextConnectionBadge); @@ -90,8 +94,10 @@ test('expect badges to be gray when not reachable', async () => { mocks.getCurrentKubeContextState.mockReturnValue({ error: undefined, reachable: false, - deploymentsCount: 0, - podsCount: 0, + resources: { + pods: [], + deployments: [], + }, } as ContextState); // no current ContextState render(KubernetesCurrentContextConnectionBadge); @@ -104,8 +110,10 @@ test('expect no tooltip when no error', async () => { mocks.getCurrentKubeContextState.mockReturnValue({ error: undefined, reachable: false, - deploymentsCount: 0, - podsCount: 0, + resources: { + pods: [], + deployments: [], + }, } as ContextState); // no current ContextState render(KubernetesCurrentContextConnectionBadge); @@ -118,8 +126,10 @@ test('expect tooltip when error', async () => { mocks.getCurrentKubeContextState.mockReturnValue({ error: 'error message', reachable: false, - deploymentsCount: 0, - podsCount: 0, + resources: { + pods: [], + deployments: [], + }, } as ContextState); // no current ContextState render(KubernetesCurrentContextConnectionBadge);