Skip to content

Commit

Permalink
feat(topology): remove usage of k8s plugin from topology & tekton plu…
Browse files Browse the repository at this point in the history
…gins (#1869)

feat(topology): remove k8s plugin dependency from topology & tekton
  • Loading branch information
debsmita1 authored Aug 2, 2024
1 parent b4ec072 commit ae7d8ee
Show file tree
Hide file tree
Showing 31 changed files with 522 additions and 89 deletions.
9 changes: 7 additions & 2 deletions plugins/shared-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,17 @@
"postpack": "backstage-cli package postpack"
},
"dependencies": {
"@backstage/catalog-model": "1.5.0",
"@backstage/core-plugin-api": "^1.9.3",
"@backstage/plugin-kubernetes-common": "0.8.0",
"@backstage/plugin-kubernetes-react": "0.4.0",
"@kubernetes/client-node": "^0.20.0",
"classnames": "^2.3.2",
"date-fns": "^2.30.0",
"file-saver": "^2.0.5",
"lodash": "^4.17.21",
"mathjs": "^11.11.2"
"mathjs": "^11.11.2",
"react-use": "^17.5.0"
},
"peerDependencies": {
"react": "^16.13.1 || ^17.0.0 || ^18.0.0"
Expand All @@ -48,8 +53,8 @@
"@testing-library/jest-dom": "6.4.8",
"@testing-library/react": "14.3.1",
"@testing-library/user-event": "14.5.2",
"@types/node": "18.19.34",
"@types/file-saver": "2.0.7",
"@types/node": "18.19.34",
"cross-fetch": "4.0.0",
"msw": "1.3.3"
},
Expand Down
1 change: 1 addition & 0 deletions plugins/shared-react/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { useDebounceCallback } from './debounce';
export { useDeepCompareMemoize } from './useDeepCompareMemoize';
export { useKubernetesObjects } from './useKubernetesObjects';
94 changes: 94 additions & 0 deletions plugins/shared-react/src/hooks/useKubernetesObjects.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// This file is a replica of useKubernetesObjects.ts & auth.ts from the Backstage upstream, created to address the issue https://issues.redhat.com/browse/RHIDP-3126

import { useCallback } from 'react';
import useAsyncRetry from 'react-use/esm/useAsyncRetry';
import useInterval from 'react-use/esm/useInterval';

import { Entity } from '@backstage/catalog-model';
import { ApiRef, useApi } from '@backstage/core-plugin-api';
import {
KubernetesRequestBody,
ObjectsByEntityResponse,
} from '@backstage/plugin-kubernetes-common';
import {
KubernetesApi,
KubernetesAuthProvidersApi,
} from '@backstage/plugin-kubernetes-react';

/**
*
* @public
*/
export interface KubernetesObjects {
kubernetesObjects?: ObjectsByEntityResponse;
loading: boolean;
error?: string;
}

const generateAuth = async (
entity: Entity,
kubernetesApi: KubernetesApi,
kubernetesAuthProvidersApi: KubernetesAuthProvidersApi,
) => {
const clusters = await kubernetesApi.getClusters();

const authProviders: string[] = [
...new Set(
clusters.map(
c =>
`${c.authProvider}${
c.oidcTokenProvider ? `.${c.oidcTokenProvider}` : ''
}`,
),
),
];

let requestBody: KubernetesRequestBody = {
entity,
};
for (const authProviderStr of authProviders) {
requestBody = await kubernetesAuthProvidersApi.decorateRequestBodyForAuth(
authProviderStr,
requestBody,
);
}
return requestBody.auth ?? {};
};

/**
*
* @public
*/
export const useKubernetesObjects = (
entity: Entity,
kubernetesApiRef: ApiRef<KubernetesApi>,
kubernetesAuthProvidersApiRef: ApiRef<KubernetesAuthProvidersApi>,
intervalMs: number = 10000,
): KubernetesObjects => {
const kubernetesApi = useApi(kubernetesApiRef);
const kubernetesAuthProvidersApi = useApi(kubernetesAuthProvidersApiRef);
const getObjects = useCallback(async (): Promise<ObjectsByEntityResponse> => {
const auth = await generateAuth(
entity,
kubernetesApi,
kubernetesAuthProvidersApi,
);
return await kubernetesApi.getObjectsByEntity({
auth,
entity,
});
}, [kubernetesApi, entity, kubernetesAuthProvidersApi]);

const { value, loading, error, retry } = useAsyncRetry(
() => getObjects(),
[getObjects],
);

useInterval(() => retry(), intervalMs);

return {
kubernetesObjects: value,
loading,
error: error?.message,
};
};
2 changes: 1 addition & 1 deletion plugins/tekton/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ The Tekton plugin enables you to visualize the `PipelineRun` resources available

#### Prerequisites

- The Kubernetes plugins including `@backstage/plugin-kubernetes` and `@backstage/plugin-kubernetes-backend` are installed and configured by following the [installation](https://backstage.io/docs/features/kubernetes/installation) and [configuration](https://backstage.io/docs/features/kubernetes/configuration) guides.
- The Kubernetes backend plugin `@backstage/plugin-kubernetes-backend` is installed and configured by following the [installation](https://backstage.io/docs/features/kubernetes/installation) and [configuration](https://backstage.io/docs/features/kubernetes/configuration) guides.

- The following `customResources` component is added in the [`app-config.yaml`](https://backstage.io/docs/features/kubernetes/configuration#configuring-kubernetes-clusters) file:
```yaml
Expand Down
44 changes: 22 additions & 22 deletions plugins/tekton/dev/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@ import { Entity } from '@backstage/catalog-model';
import { createDevApp } from '@backstage/dev-utils';
import { EntityProvider } from '@backstage/plugin-catalog-react';
import {
EntityKubernetesContent,
KubernetesApi,
kubernetesApiRef,
KubernetesProxyApi,
kubernetesProxyApiRef,
} from '@backstage/plugin-kubernetes';
} from '@backstage/plugin-kubernetes-react';
import { permissionApiRef } from '@backstage/plugin-permission-react';
import { MockPermissionApi, TestApiProvider } from '@backstage/test-utils';

Expand All @@ -23,6 +20,11 @@ import {
} from '../src/__fixtures__/advancedClusterSecurityData';
import { enterpriseContractResult } from '../src/__fixtures__/enterpriseContractData';
import { TektonCI, tektonPlugin } from '../src/plugin';
import {
kubernetesApiRef,
kubernetesAuthProvidersApiRef,
kubernetesProxyApiRef,
} from '../src/types/types';

const mockEntity: Entity = {
apiVersion: 'backstage.io/v1alpha1',
Expand Down Expand Up @@ -168,6 +170,21 @@ class MockKubernetesClient implements KubernetesApi {
}
}

const mockKubernetesAuthProviderApiRef = {
decorateRequestBodyForAuth: async () => {
return {
entity: {
apiVersion: 'v1',
kind: 'xyz',
metadata: { name: 'hey' },
},
};
},
getCredentials: async () => {
return {};
},
};

createDevApp()
.addThemes(createDevAppThemes())
.addPage({
Expand All @@ -180,6 +197,7 @@ createDevApp()
],
[kubernetesProxyApiRef, new MockKubernetesProxyApi()],
[permissionApiRef, mockPermissionApi],
[kubernetesAuthProvidersApiRef, mockKubernetesAuthProviderApiRef],
]}
>
<EntityProvider entity={mockEntity}>
Expand All @@ -190,23 +208,5 @@ createDevApp()
title: 'Tekton CI',
path: '/tekton',
})
.addPage({
element: (
<TestApiProvider
apis={[
[
kubernetesApiRef,
new MockKubernetesClient(mockKubernetesPlrResponse),
],
]}
>
<EntityProvider entity={mockEntity}>
<EntityKubernetesContent />
</EntityProvider>
</TestApiProvider>
),
title: 'k8s Page',
path: '/kubernetes',
})
.registerPlugin(tektonPlugin)
.render();
1 change: 1 addition & 0 deletions plugins/tekton/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"@backstage/plugin-catalog-react": "^1.12.2",
"@backstage/plugin-kubernetes": "^0.11.12",
"@backstage/plugin-kubernetes-common": "^0.8.1",
"@backstage/plugin-kubernetes-react": "^0.4.1",
"@backstage/theme": "^0.5.6",
"@janus-idp/shared-react": "2.9.0",
"@backstage/plugin-permission-react": "^0.4.24",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React from 'react';

import { Progress } from '@backstage/core-components';
import { useApi } from '@backstage/core-plugin-api';
import { kubernetesProxyApiRef } from '@backstage/plugin-kubernetes';

import {
ACSCheckResults,
Expand All @@ -17,7 +16,10 @@ import { Grid, Paper, Typography } from '@material-ui/core';
import { PipelineRunKind, TaskRunKind } from '@janus-idp/shared-react';

import { TektonResourcesContext } from '../../hooks/TektonResourcesContext';
import { TektonResourcesContextData } from '../../types/types';
import {
kubernetesProxyApiRef,
TektonResourcesContextData,
} from '../../types/types';

type PipelineRunOutputProps = {
pipelineRun: PipelineRunKind;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react';

import { useApi } from '@backstage/core-plugin-api';
import { kubernetesProxyApiRef } from '@backstage/plugin-kubernetes';

import { V1Pod } from '@kubernetes/client-node';
import { createStyles, Link, makeStyles, Theme } from '@material-ui/core';
Expand All @@ -12,7 +11,10 @@ import { downloadLogFile } from '@janus-idp/shared-react';

import { TektonResourcesContext } from '../../hooks/TektonResourcesContext';
import { ContainerScope } from '../../hooks/usePodLogsOfPipelineRun';
import { TektonResourcesContextData } from '../../types/types';
import {
kubernetesProxyApiRef,
TektonResourcesContextData,
} from '../../types/types';
import { getPodLogs } from '../../utils/log-downloader-utils';

const useStyles = makeStyles((theme: Theme) =>
Expand Down
2 changes: 1 addition & 1 deletion plugins/tekton/src/hooks/useAllWatchResources.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { KubernetesObjects } from '@backstage/plugin-kubernetes';
import { KubernetesObjects } from '@backstage/plugin-kubernetes-react';

import { renderHook } from '@testing-library/react';

Expand Down
2 changes: 1 addition & 1 deletion plugins/tekton/src/hooks/useAllWatchResources.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useEffect, useMemo, useState } from 'react';

import { KubernetesObjects } from '@backstage/plugin-kubernetes';
import { KubernetesObjects } from '@backstage/plugin-kubernetes-react';

import { useDeepCompareMemoize } from '@janus-idp/shared-react';

Expand Down
10 changes: 5 additions & 5 deletions plugins/tekton/src/hooks/usePodContainerLogs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import React from 'react';
import { useAsync } from 'react-use';

import { useApi } from '@backstage/core-plugin-api';
import {
ContainerScope,
kubernetesProxyApiRef,
} from '@backstage/plugin-kubernetes';
import { ContainerScope } from '@backstage/plugin-kubernetes-react';

import { V1Pod } from '@kubernetes/client-node';

import { TektonResourcesContextData } from '../types/types';
import {
kubernetesProxyApiRef,
TektonResourcesContextData,
} from '../types/types';
import { TektonResourcesContext } from './TektonResourcesContext';

interface PodContainerLogsOptions {
Expand Down
6 changes: 4 additions & 2 deletions plugins/tekton/src/hooks/usePodLogsOfPipelineRun.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import useAsyncRetry from 'react-use/lib/useAsyncRetry';
import useInterval from 'react-use/lib/useInterval';

import { useApi } from '@backstage/core-plugin-api';
import { kubernetesProxyApiRef } from '@backstage/plugin-kubernetes';

import { V1Container, V1Pod } from '@kubernetes/client-node';

import { TektonResourcesContextData } from '../types/types';
import {
kubernetesProxyApiRef,
TektonResourcesContextData,
} from '../types/types';
import { TektonResourcesContext } from './TektonResourcesContext';

export interface ContainerScope {
Expand Down
2 changes: 1 addition & 1 deletion plugins/tekton/src/hooks/useResourcesClusters.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { KubernetesObjects } from '@backstage/plugin-kubernetes';
import { KubernetesObjects } from '@backstage/plugin-kubernetes-react';

import { renderHook } from '@testing-library/react';

Expand Down
2 changes: 1 addition & 1 deletion plugins/tekton/src/hooks/useResourcesClusters.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useEffect, useState } from 'react';

import { KubernetesObjects } from '@backstage/plugin-kubernetes';
import { KubernetesObjects } from '@backstage/plugin-kubernetes-react';

import { useDeepCompareMemoize } from '@janus-idp/shared-react';

Expand Down
8 changes: 5 additions & 3 deletions plugins/tekton/src/hooks/useTektonObjectResponse.test.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import { act } from 'react';

import { useKubernetesObjects } from '@backstage/plugin-kubernetes';

import { renderHook, waitFor } from '@testing-library/react';

import { useKubernetesObjects } from '@janus-idp/shared-react';

import { mockKubernetesPlrResponse } from '../__fixtures__/1-pipelinesData';
import { kubernetesObjects } from '../__fixtures__/kubernetesObject';
import { ModelsPlural } from '../models';
import { useTektonObjectsResponse } from './useTektonObjectsResponse';

const watchedResources = [ModelsPlural.pipelineruns, ModelsPlural.taskruns];

jest.mock('@backstage/plugin-kubernetes', () => ({
jest.mock('@janus-idp/shared-react', () => ({
useKubernetesObjects: jest.fn(),
useDeepCompareMemoize: (val: any) => val,
useDebounceCallback: (val: any) => jest.fn(val),
}));

const mockUseKubernetesObjects = useKubernetesObjects as jest.Mock;
Expand Down
Loading

0 comments on commit ae7d8ee

Please sign in to comment.