adding changeset,api-report,addressing ci check

Signed-off-by: Ruben Vallejo <rvallejo@vmware.com>
This commit is contained in:
Ruben Vallejo
2023-02-07 15:38:33 -05:00
parent 1fef8423ce
commit 804f6d16b0
7 changed files with 53 additions and 33 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-kubernetes-backend': minor
---
PermissionApi of type PermissionEvaluator must now be passed as a parameter when calling proxy.createRequestHandler() for the KubernetesProxyEndpoint. Kubernetes `/proxy` endpoint now requires two tokens in its header per request.The field `X-Kubernetes-Authentication` needs the value of a authentication authorities' bearer token.The field `Authorization` should contain a backstage identity token.
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-kubernetes-common': patch
---
Introduced proxy permission types to be used with the kubernetes proxy endpoint's permission framework integration.
+7 -1
View File
@@ -17,6 +17,7 @@ import { KubernetesRequestAuth } from '@backstage/plugin-kubernetes-common';
import type { KubernetesRequestBody } from '@backstage/plugin-kubernetes-common';
import { Logger } from 'winston';
import type { ObjectsByEntityResponse } from '@backstage/plugin-kubernetes-common';
import { PermissionEvaluator } from '@backstage/plugin-permission-common';
import { PluginEndpointDiscovery } from '@backstage/backend-common';
import type { RequestHandler } from 'express';
import { TokenCredential } from '@azure/identity';
@@ -200,6 +201,7 @@ export class KubernetesBuilder {
clusterSupplier: KubernetesClustersSupplier,
catalogApi: CatalogApi,
proxy: KubernetesProxy,
permissionApi: PermissionEvaluator,
): express.Router;
// (undocumented)
protected buildServiceLocator(
@@ -271,6 +273,8 @@ export interface KubernetesEnvironment {
config: Config;
// (undocumented)
logger: Logger;
// (undocumented)
permissions: PermissionEvaluator;
}
// @public
@@ -340,7 +344,7 @@ export type KubernetesObjectTypes =
export class KubernetesProxy {
constructor(logger: Logger, clusterSupplier: KubernetesClustersSupplier);
// (undocumented)
createRequestHandler(): RequestHandler;
createRequestHandler(permissionApi: PermissionEvaluator): RequestHandler;
}
// @public
@@ -418,6 +422,8 @@ export interface RouterOptions {
discovery: PluginEndpointDiscovery;
// (undocumented)
logger: Logger;
// (undocumented)
permissions: PermissionEvaluator;
}
// @public (undocumented)
@@ -30,6 +30,10 @@ import {
HEADER_KUBERNETES_CLUSTER,
KubernetesProxy,
} from './KubernetesProxy';
import {
AuthorizeResult,
PermissionEvaluator,
} from '@backstage/plugin-permission-common';
describe('KubernetesProxy', () => {
let proxy: KubernetesProxy;
@@ -64,6 +68,11 @@ describe('KubernetesProxy', () => {
getClusters: jest.fn(),
};
const permissions: jest.Mocked<PermissionEvaluator> = {
authorize: jest.fn(),
authorizeConditional: jest.fn(),
};
beforeEach(() => {
jest.resetAllMocks();
proxy = new KubernetesProxy(getVoidLogger(), clusterSupplier);
@@ -71,13 +80,16 @@ describe('KubernetesProxy', () => {
it('should return a ERROR_NOT_FOUND if no clusters are found', async () => {
clusterSupplier.getClusters.mockResolvedValue([]);
permissions.authorize.mockReturnValue(
Promise.resolve([{ result: AuthorizeResult.ALLOW }]),
);
const req = buildMockRequest('test', 'api');
const { res, next } = getMockRes();
await expect(proxy.createRequestHandler()(req, res, next)).rejects.toThrow(
NotFoundError,
);
await expect(
proxy.createRequestHandler(permissions)(req, res, next),
).rejects.toThrow(NotFoundError);
});
it('should pass the exact response from Kubernetes', async () => {
@@ -100,7 +112,13 @@ describe('KubernetesProxy', () => {
authProvider: 'serviceAccount',
},
] as ClusterDetails[]);
const app = express().use('/mountpath', proxy.createRequestHandler());
const app = express().use(
'/mountpath',
proxy.createRequestHandler(permissions),
);
permissions.authorize.mockReturnValue(
Promise.resolve([{ result: AuthorizeResult.ALLOW }]),
);
const requestPromise = request(app)
.get('/mountpath/api')
.set(HEADER_KUBERNETES_CLUSTER, 'cluster1');
+10
View File
@@ -3,6 +3,7 @@
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
import { BasicPermission } from '@backstage/plugin-permission-common';
import { Entity } from '@backstage/catalog-model';
import type { JsonObject } from '@backstage/types';
import { PodStatus } from '@kubernetes/client-node';
@@ -206,6 +207,9 @@ export interface JobsFetchResponse {
type: 'jobs';
}
// @alpha
export const kubernetesClusterPermissions: BasicPermission[];
// @public (undocumented)
export type KubernetesErrorTypes =
| 'BAD_REQUEST'
@@ -217,6 +221,12 @@ export type KubernetesErrorTypes =
// @public (undocumented)
export type KubernetesFetchError = StatusError | RawFetchError;
// @alpha
export const kubernetesProxyCreatePermission: BasicPermission;
// @alpha
export const kubernetesProxyReadPermission: BasicPermission;
// @public (undocumented)
export interface KubernetesRequestAuth {
// (undocumented)
+4 -1
View File
@@ -16,7 +16,7 @@
import { createPermission } from '@backstage/plugin-permission-common';
/** This permission is used to authorize actions that involve using the kubernetes Proxy Endpoint /proxy
/** This permission is used to authorize `read` actions that involve using the kubernetes Proxy Endpoint /proxy
* @alpha
*/
export const kubernetesProxyReadPermission = createPermission({
@@ -24,6 +24,9 @@ export const kubernetesProxyReadPermission = createPermission({
attributes: { action: 'read' },
});
/** This permission is used to authorize `create` actions that involve using the kubernetes Proxy Endpoint /proxy
* @alpha
*/
export const kubernetesProxyCreatePermission = createPermission({
name: 'kubernetes.proxy.create',
attributes: { action: 'create' },
-27
View File
@@ -7463,32 +7463,6 @@ __metadata:
languageName: unknown
linkType: soft
"@backstage/plugin-proxy-restrict@^0.0.0, @backstage/plugin-proxy-restrict@workspace:plugins/proxy-restrict":
version: 0.0.0-use.local
resolution: "@backstage/plugin-proxy-restrict@workspace:plugins/proxy-restrict"
dependencies:
"@backstage/cli": "workspace:^"
"@backstage/core-app-api": "workspace:^"
"@backstage/core-components": "workspace:^"
"@backstage/core-plugin-api": "workspace:^"
"@backstage/dev-utils": "workspace:^"
"@backstage/test-utils": "workspace:^"
"@backstage/theme": "workspace:^"
"@material-ui/core": ^4.12.2
"@material-ui/icons": ^4.9.1
"@material-ui/lab": ^4.0.0-alpha.57
"@testing-library/jest-dom": ^5.10.1
"@testing-library/react": ^12.1.3
"@testing-library/user-event": ^14.0.0
"@types/node": "*"
cross-fetch: ^3.1.5
msw: ^0.49.0
react-use: ^17.2.4
peerDependencies:
react: ^16.13.1 || ^17.0.0
languageName: unknown
linkType: soft
"@backstage/plugin-rollbar-backend@workspace:^, @backstage/plugin-rollbar-backend@workspace:plugins/rollbar-backend":
version: 0.0.0-use.local
resolution: "@backstage/plugin-rollbar-backend@workspace:plugins/rollbar-backend"
@@ -22496,7 +22470,6 @@ __metadata:
"@backstage/plugin-pagerduty": "workspace:^"
"@backstage/plugin-permission-react": "workspace:^"
"@backstage/plugin-playlist": "workspace:^"
"@backstage/plugin-proxy-restrict": ^0.0.0
"@backstage/plugin-rollbar": "workspace:^"
"@backstage/plugin-scaffolder": "workspace:^"
"@backstage/plugin-scaffolder-react": "workspace:^"