From f3a50cbd618bb458fbd51c4a41bb5f661c17e7bb Mon Sep 17 00:00:00 2001 From: Evangelos Skopelitis Date: Thu, 12 Dec 2024 13:21:23 -0500 Subject: [PATCH 1/5] frontend: ActionsNotifier: Adjust keys for snackbars This change adds a unique refKey for error states, separate from success states, and creates a unique key for every snackbar. This addresses a regression where failure notifications would not appear in the UI. Fixes: #2655 Signed-off-by: Evangelos Skopelitis change --- frontend/src/components/common/ActionsNotifier.tsx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/common/ActionsNotifier.tsx b/frontend/src/components/common/ActionsNotifier.tsx index 7a2505bdf5..afb258e6b6 100644 --- a/frontend/src/components/common/ActionsNotifier.tsx +++ b/frontend/src/components/common/ActionsNotifier.tsx @@ -51,16 +51,20 @@ function PureActionsNotifier({ dispatch, clusterActions }: PureActionsNotifierPr } const prevKey = snackbarRefs.current[clusterAction.id]; - const uniqueKey = clusterAction.key || clusterAction.id; + const uniqueKey = `${clusterAction.key || clusterAction.id}-${Date.now()}`; if (prevKey && prevKey !== uniqueKey) { closeSnackbar(prevKey); } if (clusterAction.message) { - // Check for completed actions + // Check for success or error states const refKey = - clusterAction.state === 'complete' ? `${clusterAction.id}-complete` : clusterAction.id; + clusterAction.state === 'complete' + ? `${clusterAction.id}-complete` + : clusterAction.state === 'error' + ? `${clusterAction.id}-error` + : clusterAction.id; if (!snackbarRefs.current[refKey]) { snackbarRefs.current[refKey] = uniqueKey; From dba3653fa38e5e7fed47059cd0658adb9d0d32ab Mon Sep 17 00:00:00 2001 From: Phil Huang Date: Sat, 14 Dec 2024 02:27:35 +0800 Subject: [PATCH 2/5] docs(platforms): Add support for Red Hat OpenShift After actually installing headlamp according to the in-cluster installation file, Red Hat OpenShift can run headlamp without any modification. Signed-off-by: Phil Huang --- docs/platforms.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/platforms.md b/docs/platforms.md index cc50505c34..044cffba06 100644 --- a/docs/platforms.md +++ b/docs/platforms.md @@ -24,7 +24,7 @@ The "works" column refers to the overall Kubernetes-related functionality when r | [Microsoft AKS](https://azure.microsoft.com/) | ✔️ | - Working fine in-cluster and with the desktop application. | | [Minikube](https://minikube.sigs.k8s.io/) | ✔️ | - For exposing with an ingress, enable ingresses with `minikube addons enable ingress`:
- There are docs about the [development](./development/index.md#minikube-in-cluster) with Minikube. | | [Vultr Kubernetes Engine](https://www.vultr.com/kubernetes/) | ✔️ | - Simple to install / expose with the regular [in-cluster instructions](https://headlamp.dev/docs/latest/installation/in-cluster/). | - +| [Red Hat OpenShift](https://www.redhat.com/en/technologies/cloud-computing/openshift) | ✔️ | - Simple to install / expose with the regular [in-cluster instructions](https://headlamp.dev/docs/latest/installation/in-cluster/). | ## Tested Browsers We mostly test with 'modern browsers' defined as the latest version and two older versions. But we try to make Headlamp work with web standards, so it's quite likely other standards-conforming browsers will also work. From 16cba5d84b277c047cc1642a999686f72720974f Mon Sep 17 00:00:00 2001 From: Jan Jansen Date: Mon, 16 Dec 2024 10:19:17 +0100 Subject: [PATCH 3/5] frontend: fix location import on mutli delete button Signed-off-by: Jan Jansen --- .../src/components/common/Resource/DeleteMultipleButton.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/frontend/src/components/common/Resource/DeleteMultipleButton.tsx b/frontend/src/components/common/Resource/DeleteMultipleButton.tsx index 1226f233b4..35c40dad4a 100644 --- a/frontend/src/components/common/Resource/DeleteMultipleButton.tsx +++ b/frontend/src/components/common/Resource/DeleteMultipleButton.tsx @@ -2,6 +2,7 @@ import _ from 'lodash'; import React from 'react'; import { useTranslation } from 'react-i18next'; import { useDispatch } from 'react-redux'; +import { useLocation } from 'react-router-dom'; import { KubeObject } from '../../../lib/k8s/KubeObject'; import { CallbackActionOptions, clusterAction } from '../../../redux/clusterActionSlice'; import { @@ -43,6 +44,7 @@ export default function DeleteMultipleButton(props: DeleteMultipleButtonProps) { const { items, options, afterConfirm, buttonStyle } = props; const [openAlert, setOpenAlert] = React.useState(false); const { t } = useTranslation(['translation']); + const location = useLocation(); const dispatchDeleteEvent = useEventCallback(HeadlampEventType.DELETE_RESOURCES); const deleteFunc = React.useCallback( From ce501818982d293afef81f66c5dd17d15cda18f8 Mon Sep 17 00:00:00 2001 From: Oleksandr Dubenko Date: Mon, 16 Dec 2024 16:02:55 +0100 Subject: [PATCH 4/5] frontend: Fix useKubeObjectLists when deselecting namespaces Signed-off-by: Oleksandr Dubenko --- .../lib/k8s/api/v2/useKubeObjectList.test.tsx | 50 +++++++++++++++++++ .../src/lib/k8s/api/v2/useKubeObjectList.ts | 13 +++++ 2 files changed, 63 insertions(+) diff --git a/frontend/src/lib/k8s/api/v2/useKubeObjectList.test.tsx b/frontend/src/lib/k8s/api/v2/useKubeObjectList.test.tsx index 5b8957ad56..4018f1a533 100644 --- a/frontend/src/lib/k8s/api/v2/useKubeObjectList.test.tsx +++ b/frontend/src/lib/k8s/api/v2/useKubeObjectList.test.tsx @@ -4,6 +4,7 @@ import { kubeObjectListQuery, ListResponse, makeListRequests, + useKubeObjectList, useWatchKubeObjectLists, } from './useKubeObjectList'; import * as websocket from './webSocket'; @@ -81,6 +82,16 @@ const mockClass = class { static apiVersion = 'v1'; static apiName = 'pods'; + static apiEndpoint = { + apiInfo: [ + { + group: '', + resource: 'pods', + version: 'v1', + }, + ], + }; + constructor(public jsonData: any) {} } as any; @@ -221,3 +232,42 @@ describe('useWatchKubeObjectLists', () => { ).toBe(objectB); }); }); + +describe('useKubeObjectList', () => { + it('should call useKubeObjectList with 1 namespace after reducing amount of namespaces', async () => { + const spy = vi.spyOn(websocket, 'useWebSockets'); + const queryClient = new QueryClient(); + + queryClient.setQueryData(['kubeObject', 'list', 'v1', 'pods', 'default', 'a', {}], { + list: { items: [], metadata: { resourceVersion: '0' } }, + cluster: 'default', + namespace: 'a', + }); + queryClient.setQueryData(['kubeObject', 'list', 'v1', 'pods', 'default', 'b', {}], { + list: { items: [], metadata: { resourceVersion: '0' } }, + cluster: 'default', + namespace: 'b', + }); + + const result = renderHook( + (props: {}) => + useKubeObjectList({ + kubeObjectClass: mockClass, + requests: [{ cluster: 'default', namespaces: ['a', 'b'] }], + ...props, + }), + { + wrapper: ({ children }) => ( + {children} + ), + } + ); + + result.rerender({ requests: [{ cluster: 'default', namespaces: ['a'] }] }); + + expect(spy.mock.calls[0][0].connections.length).toBe(0); // initial render + expect(spy.mock.calls[1][0].connections.length).toBe(2); // new connections with 'a' and 'b' namespaces + expect(spy.mock.calls[2][0].connections.length).toBe(2); // rerender with new props + expect(spy.mock.calls[3][0].connections.length).toBe(1); // updated connections after we removed namespace 'b' + }); +}); diff --git a/frontend/src/lib/k8s/api/v2/useKubeObjectList.ts b/frontend/src/lib/k8s/api/v2/useKubeObjectList.ts index 4e11f8033f..9de0a6f737 100644 --- a/frontend/src/lib/k8s/api/v2/useKubeObjectList.ts +++ b/frontend/src/lib/k8s/api/v2/useKubeObjectList.ts @@ -306,6 +306,19 @@ export function useKubeObjectList({ setListsToWatch([...listsToWatch, ...listsNotYetWatched]); } + const listsToStopWatching = listsToWatch.filter( + watching => + requests.find(request => + watching.cluster === request?.cluster && request.namespaces && watching.namespace + ? request.namespaces?.includes(watching.namespace) + : true + ) === undefined + ); + + if (listsToStopWatching.length > 0) { + setListsToWatch(listsToWatch.filter(it => !listsToStopWatching.includes(it))); + } + useWatchKubeObjectLists({ lists: shouldWatch ? listsToWatch : [], endpoint, From ed1f958dfcc248fe06c4e5e4ba9091bf6338536c Mon Sep 17 00:00:00 2001 From: Kautilya Tripathi Date: Wed, 18 Dec 2024 05:19:51 +0530 Subject: [PATCH 5/5] charts: Fix pvc storage requirement Added validation to ensure required fields are provided. This will fail chart installation if size is not specified when PVC is enabled. Signed-off-by: Kautilya Tripathi --- charts/headlamp/templates/pvc.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/headlamp/templates/pvc.yaml b/charts/headlamp/templates/pvc.yaml index c88b49d6d0..3c9ec9335d 100644 --- a/charts/headlamp/templates/pvc.yaml +++ b/charts/headlamp/templates/pvc.yaml @@ -17,7 +17,7 @@ spec: {{- end}} resources: requests: - storage: {{ .Values.persistentVolumeClaim.size }} + storage: {{ required "A valid .Values.persistentVolumeClaim.size entry required!" .Values.persistentVolumeClaim.size }} {{- with .Values.persistentVolumeClaim.volumeMode }} volumeMode: {{ . }} {{- end }}