From 0d526c85549081647abe0f3c50d3b91e163f7998 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Date: Mon, 18 Dec 2023 17:22:30 -0500 Subject: [PATCH 1/5] feat: Make PodExecTerminal UI OptIn Signed-off-by: Carlos Esteban Lopez --- .changeset/sixty-shoes-prove.md | 6 ++ plugins/kubernetes-react/config.d.ts | 31 +++++++++ plugins/kubernetes-react/package.json | 4 +- .../Pods/PodDrawer/ContainerCard.tsx | 17 +++-- plugins/kubernetes-react/src/hooks/index.ts | 1 + .../useIsPodExecTerminalEnabled.test.tsx | 64 +++++++++++++++++++ .../src/hooks/useIsPodExecTerminalEnabled.ts | 27 ++++++++ .../useIsPodExecTerminalSupported.test.ts | 2 +- .../hooks/useIsPodExecTerminalSupported.ts | 1 + 9 files changed, 145 insertions(+), 8 deletions(-) create mode 100644 .changeset/sixty-shoes-prove.md create mode 100644 plugins/kubernetes-react/config.d.ts create mode 100644 plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.test.tsx create mode 100644 plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.ts diff --git a/.changeset/sixty-shoes-prove.md b/.changeset/sixty-shoes-prove.md new file mode 100644 index 0000000000..67a019f1ea --- /dev/null +++ b/.changeset/sixty-shoes-prove.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-kubernetes-backend': patch +'@backstage/plugin-kubernetes-react': patch +--- + +Make PodExecTerminal UI OptIn diff --git a/plugins/kubernetes-react/config.d.ts b/plugins/kubernetes-react/config.d.ts new file mode 100644 index 0000000000..d8f6ba8ca9 --- /dev/null +++ b/plugins/kubernetes-react/config.d.ts @@ -0,0 +1,31 @@ +import { PodExecTerminal } from './src/components/PodExecTerminal/PodExecTerminal'; +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export interface Config { + kubernetes?: { + /** + * Pod Exec Terminal config + */ + podExecTerminal?: { + /** + * Enable `PodExecTerminal` UI feature + * @visibility frontend + */ + enable?: boolean; + }; + }; +} diff --git a/plugins/kubernetes-react/package.json b/plugins/kubernetes-react/package.json index 8389b4d2a9..d85cb7ba35 100644 --- a/plugins/kubernetes-react/package.json +++ b/plugins/kubernetes-react/package.json @@ -14,6 +14,7 @@ "role": "web-library" }, "sideEffects": false, + "configSchema": "config.d.ts", "scripts": { "start": "backstage-cli package start", "build": "backstage-cli package build", @@ -60,6 +61,7 @@ "msw": "^1.3.1" }, "files": [ - "dist" + "dist", + "config.d.ts" ] } diff --git a/plugins/kubernetes-react/src/components/Pods/PodDrawer/ContainerCard.tsx b/plugins/kubernetes-react/src/components/Pods/PodDrawer/ContainerCard.tsx index db70f92160..592a93e3ea 100644 --- a/plugins/kubernetes-react/src/components/Pods/PodDrawer/ContainerCard.tsx +++ b/plugins/kubernetes-react/src/components/Pods/PodDrawer/ContainerCard.tsx @@ -27,6 +27,7 @@ import { IContainer, IContainerStatus } from 'kubernetes-models/v1'; import { DateTime } from 'luxon'; import React from 'react'; +import { useIsPodExecTerminalEnabled } from '../../../hooks'; import { bytesToMiB, formatMillicores } from '../../../utils/resources'; import { PodExecTerminalDialog } from '../../PodExecTerminal/PodExecTerminalDialog'; import { ResourceUtilization } from '../../ResourceUtilization'; @@ -108,6 +109,8 @@ export const ContainerCard: React.FC = ({ containerStatus, containerMetrics, }: ContainerCardProps) => { + const isPodExecTerminalEnabled = useIsPodExecTerminalEnabled(); + // This should never be undefined if (containerSpec === undefined) { return error reading pod from cluster; @@ -228,12 +231,14 @@ export const ContainerCard: React.FC = ({ ...podScope, }} /> - + {isPodExecTerminalEnabled && ( + + )} ); diff --git a/plugins/kubernetes-react/src/hooks/index.ts b/plugins/kubernetes-react/src/hooks/index.ts index 141bc3815b..2bc519d69a 100644 --- a/plugins/kubernetes-react/src/hooks/index.ts +++ b/plugins/kubernetes-react/src/hooks/index.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +export * from './useIsPodExecTerminalEnabled'; export * from './useIsPodExecTerminalSupported'; export * from './useKubernetesObjects'; export * from './useCustomResources'; diff --git a/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.test.tsx b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.test.tsx new file mode 100644 index 0000000000..3faf81d9ae --- /dev/null +++ b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.test.tsx @@ -0,0 +1,64 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { ConfigReader } from '@backstage/core-app-api'; +import { configApiRef } from '@backstage/core-plugin-api'; +import { TestApiProvider } from '@backstage/test-utils'; +import { renderHook } from '@testing-library/react'; +import { PropsWithChildren } from 'react'; +import React from 'react'; + +import { useIsPodExecTerminalEnabled } from './useIsPodExecTerminalEnabled'; + +describe('useIsPodExecTerminalEnabled', () => { + let isPodExecTerminalEnabled: boolean | undefined; + + const apiWrapper = ({ children }: PropsWithChildren) => ( + + {children} + + ); + + it.each([ + { + condition: 'missing config', + returnValue: undefined, + }, + { condition: 'disabled', returnValue: false }, + { + condition: 'enabled', + returnValue: true, + }, + ])('Should return $returnValue if $condition', async ({ returnValue }) => { + isPodExecTerminalEnabled = returnValue; + + const { result } = renderHook(() => useIsPodExecTerminalEnabled(), { + wrapper: apiWrapper, + }); + + expect(result.current).toEqual(returnValue); + }); +}); diff --git a/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.ts b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.ts new file mode 100644 index 0000000000..683b9b9a5a --- /dev/null +++ b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.ts @@ -0,0 +1,27 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { configApiRef, useApi } from '@backstage/core-plugin-api'; + +/** + * Check if conditions for a pod exec call through the proxy endpoint are met + * + * @internal + */ +export const useIsPodExecTerminalEnabled = (): boolean | undefined => { + const configApi = useApi(configApiRef); + + return configApi.getOptionalBoolean('kubernetes.podExecTerminal.enable'); +}; diff --git a/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalSupported.test.ts b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalSupported.test.ts index 93bfb6dd4d..c4df347c6f 100644 --- a/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalSupported.test.ts +++ b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalSupported.test.ts @@ -20,7 +20,7 @@ import { useIsPodExecTerminalSupported } from './useIsPodExecTerminalSupported'; jest.mock('@backstage/core-plugin-api'); -describe('useIsClusterShellEnabled', () => { +describe('useIsPodExecTerminalSupported', () => { let clusters: { authProvider: string }[] = []; beforeEach(() => { diff --git a/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalSupported.ts b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalSupported.ts index e881951059..2483bb9412 100644 --- a/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalSupported.ts +++ b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalSupported.ts @@ -15,6 +15,7 @@ */ import { useApi } from '@backstage/core-plugin-api'; import useAsync, { AsyncState } from 'react-use/lib/useAsync'; + import { kubernetesApiRef } from '../api/types'; /** From 8ed83b5b1023790d9085cae343878e947e590ba9 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Date: Mon, 18 Dec 2023 17:26:55 -0500 Subject: [PATCH 2/5] chore: Remove unnecesary changeset package Signed-off-by: Carlos Esteban Lopez --- .changeset/sixty-shoes-prove.md | 1 - 1 file changed, 1 deletion(-) diff --git a/.changeset/sixty-shoes-prove.md b/.changeset/sixty-shoes-prove.md index 67a019f1ea..5db1586ae0 100644 --- a/.changeset/sixty-shoes-prove.md +++ b/.changeset/sixty-shoes-prove.md @@ -1,5 +1,4 @@ --- -'@backstage/plugin-kubernetes-backend': patch '@backstage/plugin-kubernetes-react': patch --- From 3b84b4b9e48be9160a0e52e7b5b383bc4b819daa Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Jaramillo Date: Thu, 4 Jan 2024 15:31:42 -0500 Subject: [PATCH 3/5] Update .changeset/sixty-shoes-prove.md Co-authored-by: Jamie Klassen Signed-off-by: Carlos Esteban Lopez Jaramillo --- .changeset/sixty-shoes-prove.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/sixty-shoes-prove.md b/.changeset/sixty-shoes-prove.md index 5db1586ae0..92edbcc079 100644 --- a/.changeset/sixty-shoes-prove.md +++ b/.changeset/sixty-shoes-prove.md @@ -1,5 +1,5 @@ --- -'@backstage/plugin-kubernetes-react': patch +'@backstage/plugin-kubernetes-react': minor --- Make PodExecTerminal UI OptIn From 7133da27dc67bfd3f4adeae0bf28a2658f1b3d0a Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Jaramillo Date: Thu, 4 Jan 2024 15:32:45 -0500 Subject: [PATCH 4/5] Update .changeset/sixty-shoes-prove.md Co-authored-by: Jamie Klassen Signed-off-by: Carlos Esteban Lopez Jaramillo --- .changeset/sixty-shoes-prove.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/sixty-shoes-prove.md b/.changeset/sixty-shoes-prove.md index 92edbcc079..fe9438eeb2 100644 --- a/.changeset/sixty-shoes-prove.md +++ b/.changeset/sixty-shoes-prove.md @@ -2,4 +2,4 @@ '@backstage/plugin-kubernetes-react': minor --- -Make PodExecTerminal UI OptIn +**BREAKING** The pod exec terminal is now disabled by default since there are several scenarios where it is known not to work. It can be re-enabled at your own risk by setting the config parameter `kubernetes.podExecTerminal.enabled` to `true`. From d98604b667b561d2c7f5b15456a549137158e291 Mon Sep 17 00:00:00 2001 From: Carlos Esteban Lopez Jaramillo Date: Thu, 4 Jan 2024 15:33:19 -0500 Subject: [PATCH 5/5] Apply suggestions from code review Co-authored-by: Jamie Klassen Signed-off-by: Carlos Esteban Lopez Jaramillo --- plugins/kubernetes-react/config.d.ts | 2 +- .../src/hooks/useIsPodExecTerminalEnabled.test.tsx | 2 +- .../kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/kubernetes-react/config.d.ts b/plugins/kubernetes-react/config.d.ts index d8f6ba8ca9..2d2b790d05 100644 --- a/plugins/kubernetes-react/config.d.ts +++ b/plugins/kubernetes-react/config.d.ts @@ -25,7 +25,7 @@ export interface Config { * Enable `PodExecTerminal` UI feature * @visibility frontend */ - enable?: boolean; + enabled?: boolean; }; }; } diff --git a/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.test.tsx b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.test.tsx index 3faf81d9ae..84e75ce529 100644 --- a/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.test.tsx +++ b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.test.tsx @@ -32,7 +32,7 @@ describe('useIsPodExecTerminalEnabled', () => { configApiRef, new ConfigReader({ kubernetes: { - podExecTerminal: { enable: isPodExecTerminalEnabled }, + podExecTerminal: { enabled: isPodExecTerminalEnabled }, }, }), ], diff --git a/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.ts b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.ts index 683b9b9a5a..7598e1c570 100644 --- a/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.ts +++ b/plugins/kubernetes-react/src/hooks/useIsPodExecTerminalEnabled.ts @@ -23,5 +23,5 @@ import { configApiRef, useApi } from '@backstage/core-plugin-api'; export const useIsPodExecTerminalEnabled = (): boolean | undefined => { const configApi = useApi(configApiRef); - return configApi.getOptionalBoolean('kubernetes.podExecTerminal.enable'); + return configApi.getOptionalBoolean('kubernetes.podExecTerminal.enabled'); };