Merge pull request #31349 from IlyaSavich/kubernetes-router-extension
Add Kubernetes Router extension point, add fetcher to custom objects provider
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
'@backstage/plugin-kubernetes-backend': minor
|
||||
'@backstage/plugin-kubernetes-node': minor
|
||||
---
|
||||
|
||||
Add possibility to extends Kubernetes REST API. Add fetcher to parameters for custom objects provider
|
||||
@@ -36,6 +36,9 @@ import {
|
||||
kubernetesObjectsProviderExtensionPoint,
|
||||
type KubernetesObjectsProviderExtensionPoint,
|
||||
KubernetesObjectsProviderFactory,
|
||||
KubernetesRouterExtensionPoint,
|
||||
kubernetesRouterExtensionPoint,
|
||||
KubernetesRouterFactory,
|
||||
type KubernetesServiceLocator,
|
||||
kubernetesServiceLocatorExtensionPoint,
|
||||
type KubernetesServiceLocatorExtensionPoint,
|
||||
@@ -157,6 +160,24 @@ class AuthStrategy implements KubernetesAuthStrategyExtensionPoint {
|
||||
}
|
||||
}
|
||||
|
||||
class CustomRouter implements KubernetesRouterExtensionPoint {
|
||||
private router: KubernetesRouterFactory | undefined;
|
||||
|
||||
getRouter() {
|
||||
return this.router;
|
||||
}
|
||||
|
||||
addRouter(router: KubernetesRouterFactory) {
|
||||
if (this.router) {
|
||||
throw new Error(
|
||||
'Multiple Kubernetes routers is not supported at this time',
|
||||
);
|
||||
}
|
||||
|
||||
this.router = router;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the backend plugin that provides the Kubernetes integration.
|
||||
* @public
|
||||
@@ -169,6 +190,7 @@ export const kubernetesPlugin = createBackendPlugin({
|
||||
const extPointAuthStrategy = new AuthStrategy();
|
||||
const extPointFetcher = new Fetcher();
|
||||
const extPointServiceLocator = new ServiceLocator();
|
||||
const extPointRouter = new CustomRouter();
|
||||
|
||||
env.registerExtensionPoint(
|
||||
kubernetesObjectsProviderExtensionPoint,
|
||||
@@ -190,6 +212,7 @@ export const kubernetesPlugin = createBackendPlugin({
|
||||
kubernetesServiceLocatorExtensionPoint,
|
||||
extPointServiceLocator,
|
||||
);
|
||||
env.registerExtensionPoint(kubernetesRouterExtensionPoint, extPointRouter);
|
||||
|
||||
env.registerInit({
|
||||
deps: {
|
||||
@@ -247,6 +270,7 @@ export const kubernetesPlugin = createBackendPlugin({
|
||||
clusterSupplier,
|
||||
serviceLocator,
|
||||
objectsProvider,
|
||||
customRouter: extPointRouter.getRouter(),
|
||||
});
|
||||
|
||||
http.use(await router.getRouter());
|
||||
|
||||
@@ -209,6 +209,7 @@ export class KubernetesInitializer {
|
||||
customResources,
|
||||
objectTypesToFetch,
|
||||
}),
|
||||
fetcher,
|
||||
clusterSupplier,
|
||||
serviceLocator,
|
||||
customResources,
|
||||
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
KubernetesFetcher,
|
||||
KubernetesServiceLocator,
|
||||
KubernetesCredential,
|
||||
kubernetesRouterExtensionPoint,
|
||||
} from '@backstage/plugin-kubernetes-node';
|
||||
import {
|
||||
HEADER_KUBERNETES_CLUSTER,
|
||||
@@ -809,4 +810,39 @@ metadata:
|
||||
'Unsupported kubernetes.serviceLocatorMethod "unsupported"',
|
||||
);
|
||||
});
|
||||
|
||||
it('custom router', async () => {
|
||||
const { server } = await startTestBackend({
|
||||
features: [
|
||||
minimalValidConfigService,
|
||||
import('@backstage/plugin-kubernetes-backend'),
|
||||
createBackendModule({
|
||||
pluginId: 'kubernetes',
|
||||
moduleId: 'testRouter',
|
||||
register(env) {
|
||||
env.registerInit({
|
||||
deps: { extension: kubernetesRouterExtensionPoint },
|
||||
async init({ extension }) {
|
||||
extension.addRouter(({ getDefault }) => {
|
||||
const router = getDefault();
|
||||
|
||||
router.get('/test', (_req, res) => {
|
||||
res.json({ status: 'ok' });
|
||||
});
|
||||
|
||||
return router;
|
||||
});
|
||||
},
|
||||
});
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
app = server;
|
||||
|
||||
const response = await request(app).get('/api/kubernetes/test');
|
||||
|
||||
expect(response.body).toEqual({ status: 'ok' });
|
||||
expect(response.status).toEqual(200);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -41,6 +41,7 @@ import {
|
||||
KubernetesClustersSupplier,
|
||||
KubernetesFetcher,
|
||||
KubernetesObjectsProvider,
|
||||
KubernetesRouterFactory,
|
||||
KubernetesServiceLocator,
|
||||
} from '@backstage/plugin-kubernetes-node';
|
||||
import { addResourceRoutesToRouter } from '../routes/resourcesRoutes';
|
||||
@@ -62,6 +63,7 @@ export interface KubernetesEnvironment {
|
||||
clusterSupplier: KubernetesClustersSupplier;
|
||||
serviceLocator: KubernetesServiceLocator;
|
||||
objectsProvider: KubernetesObjectsProvider;
|
||||
customRouter?: KubernetesRouterFactory;
|
||||
}
|
||||
|
||||
export class KubernetesRouter {
|
||||
@@ -86,6 +88,7 @@ export class KubernetesRouter {
|
||||
catalog,
|
||||
discovery,
|
||||
httpAuth,
|
||||
customRouter,
|
||||
} = this.env;
|
||||
|
||||
logger.info('Initializing Kubernetes backend');
|
||||
@@ -108,14 +111,31 @@ export class KubernetesRouter {
|
||||
authStrategyMap,
|
||||
);
|
||||
|
||||
return this.buildRouter(
|
||||
objectsProvider,
|
||||
clusterSupplier,
|
||||
catalog,
|
||||
proxy,
|
||||
permissions,
|
||||
httpAuth,
|
||||
authStrategyMap,
|
||||
return (
|
||||
customRouter?.({
|
||||
getDefault: () =>
|
||||
this.buildDefaultRouter(
|
||||
objectsProvider,
|
||||
clusterSupplier,
|
||||
catalog,
|
||||
proxy,
|
||||
permissions,
|
||||
httpAuth,
|
||||
authStrategyMap,
|
||||
),
|
||||
objectsProvider,
|
||||
clusterSupplier,
|
||||
authStrategyMap,
|
||||
}) ??
|
||||
this.buildDefaultRouter(
|
||||
objectsProvider,
|
||||
clusterSupplier,
|
||||
catalog,
|
||||
proxy,
|
||||
permissions,
|
||||
httpAuth,
|
||||
authStrategyMap,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -138,7 +158,7 @@ export class KubernetesRouter {
|
||||
});
|
||||
}
|
||||
|
||||
private buildRouter(
|
||||
private buildDefaultRouter(
|
||||
objectsProvider: KubernetesObjectsProvider,
|
||||
clusterSupplier: KubernetesClustersSupplier,
|
||||
catalog: CatalogService,
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
"@backstage/plugin-kubernetes-common": "workspace:^",
|
||||
"@backstage/types": "workspace:^",
|
||||
"@kubernetes/client-node": "1.4.0",
|
||||
"@types/express": "^4.17.6",
|
||||
"node-fetch": "^2.7.0",
|
||||
"winston": "^3.2.1"
|
||||
},
|
||||
|
||||
@@ -8,6 +8,7 @@ import { BackstageCredentials } from '@backstage/backend-plugin-api';
|
||||
import { CustomResource as CustomResource_2 } from '@backstage/plugin-kubernetes-node';
|
||||
import { CustomResourceMatcher } from '@backstage/plugin-kubernetes-common';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import type express from 'express';
|
||||
import { ExtensionPoint } from '@backstage/backend-plugin-api';
|
||||
import { FetchResponse } from '@backstage/plugin-kubernetes-common';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
@@ -198,6 +199,7 @@ export type KubernetesObjectsProviderFactory = (opts: {
|
||||
getDefault: () => Promise<KubernetesObjectsProvider_2>;
|
||||
clusterSupplier: KubernetesClustersSupplier_2;
|
||||
serviceLocator: KubernetesServiceLocator_2;
|
||||
fetcher: KubernetesFetcher_2;
|
||||
customResources: CustomResource_2[];
|
||||
objectTypesToFetch?: ObjectToFetch_2[];
|
||||
authStrategy: AuthenticationStrategy_2;
|
||||
@@ -221,6 +223,25 @@ export type KubernetesObjectTypes =
|
||||
| 'daemonsets'
|
||||
| 'secrets';
|
||||
|
||||
// @public
|
||||
export interface KubernetesRouterExtensionPoint {
|
||||
// (undocumented)
|
||||
addRouter(router: KubernetesRouterFactory): void;
|
||||
}
|
||||
|
||||
// @public
|
||||
export const kubernetesRouterExtensionPoint: ExtensionPoint<KubernetesRouterExtensionPoint>;
|
||||
|
||||
// @public
|
||||
export type KubernetesRouterFactory = (opts: {
|
||||
getDefault: () => express.Router;
|
||||
objectsProvider: KubernetesObjectsProvider_2;
|
||||
clusterSupplier: KubernetesClustersSupplier_2;
|
||||
authStrategyMap: {
|
||||
[key: string]: AuthenticationStrategy_2;
|
||||
};
|
||||
}) => express.Router;
|
||||
|
||||
// @public
|
||||
export interface KubernetesServiceLocator {
|
||||
// (undocumented)
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
KubernetesObjectsProvider,
|
||||
KubernetesServiceLocator,
|
||||
} from '@backstage/plugin-kubernetes-node';
|
||||
import type express from 'express';
|
||||
|
||||
/**
|
||||
* A factory function for creating a KubernetesObjectsProvider.
|
||||
@@ -33,6 +34,7 @@ export type KubernetesObjectsProviderFactory = (opts: {
|
||||
getDefault: () => Promise<KubernetesObjectsProvider>;
|
||||
clusterSupplier: KubernetesClustersSupplier;
|
||||
serviceLocator: KubernetesServiceLocator;
|
||||
fetcher: KubernetesFetcher;
|
||||
customResources: CustomResource[];
|
||||
objectTypesToFetch?: ObjectToFetch[];
|
||||
authStrategy: AuthenticationStrategy;
|
||||
@@ -168,3 +170,34 @@ export const kubernetesServiceLocatorExtensionPoint =
|
||||
createExtensionPoint<KubernetesServiceLocatorExtensionPoint>({
|
||||
id: 'kubernetes.service-locator',
|
||||
});
|
||||
|
||||
/**
|
||||
* A factory function for creating a kubernetes router.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type KubernetesRouterFactory = (opts: {
|
||||
getDefault: () => express.Router;
|
||||
objectsProvider: KubernetesObjectsProvider;
|
||||
clusterSupplier: KubernetesClustersSupplier;
|
||||
authStrategyMap: { [key: string]: AuthenticationStrategy };
|
||||
}) => express.Router;
|
||||
|
||||
/**
|
||||
* The interface for {@link kubernetesRouterExtensionPoint}.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export interface KubernetesRouterExtensionPoint {
|
||||
addRouter(router: KubernetesRouterFactory): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* An extension point the exposes the ability to configure a kubernetes service locator.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const kubernetesRouterExtensionPoint =
|
||||
createExtensionPoint<KubernetesRouterExtensionPoint>({
|
||||
id: 'kubernetes.router',
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user