From d8a54d0a8342965f84677a5a8e395c5c015b0e27 Mon Sep 17 00:00:00 2001 From: Aramis Date: Sat, 27 Jan 2024 22:34:40 -0500 Subject: [PATCH 01/10] feat(catalog): add support for entity policies in the new backend. Signed-off-by: Aramis --- .changeset/thirty-bags-try.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/thirty-bags-try.md diff --git a/.changeset/thirty-bags-try.md b/.changeset/thirty-bags-try.md new file mode 100644 index 0000000000..7a8156e44c --- /dev/null +++ b/.changeset/thirty-bags-try.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': minor +--- + +Add support for defining entity policies in the new backend. From 31392e59b852f4b6384cc84bb03318ade9a088bb Mon Sep 17 00:00:00 2001 From: Aramis Date: Tue, 30 Jan 2024 10:59:28 -0500 Subject: [PATCH 02/10] update to a separate catalog extension and add support for replacing Signed-off-by: Aramis --- .../src/service/CatalogPlugin.ts | 40 ++++++++++++++++++- plugins/catalog-node/api-report-alpha.md | 14 +++++++ plugins/catalog-node/src/alpha.ts | 2 + plugins/catalog-node/src/extensions.ts | 17 +++++++- 4 files changed, 71 insertions(+), 2 deletions(-) diff --git a/plugins/catalog-backend/src/service/CatalogPlugin.ts b/plugins/catalog-backend/src/service/CatalogPlugin.ts index bfe8ef5a16..5bcaaba1fb 100644 --- a/plugins/catalog-backend/src/service/CatalogPlugin.ts +++ b/plugins/catalog-backend/src/service/CatalogPlugin.ts @@ -17,7 +17,7 @@ import { createBackendPlugin, coreServices, } from '@backstage/backend-plugin-api'; -import { Entity } from '@backstage/catalog-model'; +import { Entity, EntityPolicy } from '@backstage/catalog-model'; import { CatalogBuilder, CatalogPermissionRuleInput } from './CatalogBuilder'; import { CatalogAnalysisExtensionPoint, @@ -26,6 +26,8 @@ import { catalogProcessingExtensionPoint, CatalogPermissionExtensionPoint, catalogPermissionExtensionPoint, + CatalogModelExtensionPoint, + catalogModelExtensionPoint, } from '@backstage/plugin-catalog-node/alpha'; import { CatalogProcessor, @@ -124,6 +126,33 @@ class CatalogPermissionExtensionPointImpl } } +class CatalogModelExtensionPointImpl implements CatalogModelExtensionPoint { + #entityPolicies = new Array(); + #replaced = false; + + addEntityPolicies(...policies: Array>) { + this.#entityPolicies.push(...policies.flat()); + } + + replaceEntityPolicies(...policies: Array) { + if (this.#replaced) { + throw new Error( + `You've already replaced the entity policies. If you want to add more entity policies, see 'addEntityPolicies'.`, + ); + } + this.#entityPolicies = [...policies]; + this.#replaced = true; + } + + get entityPolicies() { + return this.#entityPolicies; + } + + get replaced() { + return this.#replaced; + } +} + /** * Catalog plugin * @alpha @@ -150,6 +179,9 @@ export const catalogPlugin = createBackendPlugin({ permissionExtensions, ); + const modelExtensions = new CatalogModelExtensionPointImpl(); + env.registerExtensionPoint(catalogModelExtensionPoint, modelExtensions); + env.registerInit({ deps: { logger: coreServices.logger, @@ -193,6 +225,12 @@ export const catalogPlugin = createBackendPlugin({ builder.addLocationAnalyzers(...analysisExtensions.locationAnalyzers); builder.addPermissionRules(...permissionExtensions.permissionRules); + if (modelExtensions.replaced) { + builder.replaceEntityPolicies(modelExtensions.entityPolicies); + } else { + builder.addEntityPolicy(...modelExtensions.entityPolicies); + } + const { processingEngine, router } = await builder.build(); await processingEngine.start(); diff --git a/plugins/catalog-node/api-report-alpha.md b/plugins/catalog-node/api-report-alpha.md index 5be4b114c0..64382e56bb 100644 --- a/plugins/catalog-node/api-report-alpha.md +++ b/plugins/catalog-node/api-report-alpha.md @@ -7,6 +7,7 @@ import { CatalogApi } from '@backstage/catalog-client'; import { CatalogProcessor } from '@backstage/plugin-catalog-node'; import { EntitiesSearchFilter } from '@backstage/plugin-catalog-node'; import { Entity } from '@backstage/catalog-model'; +import { EntityPolicy } from '@backstage/catalog-model'; import { EntityProvider } from '@backstage/plugin-catalog-node'; import { ExtensionPoint } from '@backstage/backend-plugin-api'; import { PermissionRule } from '@backstage/plugin-permission-node'; @@ -24,6 +25,19 @@ export interface CatalogAnalysisExtensionPoint { // @alpha (undocumented) export const catalogAnalysisExtensionPoint: ExtensionPoint; +// @alpha (undocumented) +export interface CatalogModelExtensionPoint { + // (undocumented) + addEntityPolicies( + ...policies: Array> + ): void; + // (undocumented) + replaceEntityPolicies(...policies: Array): void; +} + +// @alpha (undocumented) +export const catalogModelExtensionPoint: ExtensionPoint; + // @alpha (undocumented) export interface CatalogPermissionExtensionPoint { // (undocumented) diff --git a/plugins/catalog-node/src/alpha.ts b/plugins/catalog-node/src/alpha.ts index 3e958d1df1..91b5bb99b6 100644 --- a/plugins/catalog-node/src/alpha.ts +++ b/plugins/catalog-node/src/alpha.ts @@ -22,3 +22,5 @@ export { catalogAnalysisExtensionPoint } from './extensions'; export type { CatalogPermissionRuleInput } from './extensions'; export type { CatalogPermissionExtensionPoint } from './extensions'; export { catalogPermissionExtensionPoint } from './extensions'; +export type { CatalogModelExtensionPoint } from './extensions'; +export { catalogModelExtensionPoint } from './extensions'; diff --git a/plugins/catalog-node/src/extensions.ts b/plugins/catalog-node/src/extensions.ts index e2ee1b4f4b..7c63e51c69 100644 --- a/plugins/catalog-node/src/extensions.ts +++ b/plugins/catalog-node/src/extensions.ts @@ -15,7 +15,7 @@ */ import { createExtensionPoint } from '@backstage/backend-plugin-api'; -import { Entity } from '@backstage/catalog-model'; +import { Entity, EntityPolicy } from '@backstage/catalog-model'; import { CatalogProcessor, EntitiesSearchFilter, @@ -45,6 +45,15 @@ export interface CatalogProcessingExtensionPoint { ): void; } +/** @alpha */ +export interface CatalogModelExtensionPoint { + addEntityPolicies( + ...policies: Array> + ): void; + + replaceEntityPolicies(...policies: Array): void; +} + /** * @alpha */ @@ -68,6 +77,12 @@ export const catalogAnalysisExtensionPoint = id: 'catalog.analysis', }); +/** @alpha */ +export const catalogModelExtensionPoint = + createExtensionPoint({ + id: 'catalog.model', + }); + /** * @alpha */ From 0aba8f018ed590ce1ef233e90179088e98775794 Mon Sep 17 00:00:00 2001 From: Aramis Date: Fri, 2 Feb 2024 15:29:27 -0500 Subject: [PATCH 03/10] add test cases for the new transformer Signed-off-by: Aramis Signed-off-by: aramissennyeydd --- .../core/policyToProcessorTransformer.test.ts | 90 +++++++++++++++++++ .../core/policyToProcessorTransformer.ts | 41 +++++++++ 2 files changed, 131 insertions(+) create mode 100644 plugins/catalog-backend/src/modules/core/policyToProcessorTransformer.test.ts create mode 100644 plugins/catalog-backend/src/modules/core/policyToProcessorTransformer.ts diff --git a/plugins/catalog-backend/src/modules/core/policyToProcessorTransformer.test.ts b/plugins/catalog-backend/src/modules/core/policyToProcessorTransformer.test.ts new file mode 100644 index 0000000000..46338ce6cb --- /dev/null +++ b/plugins/catalog-backend/src/modules/core/policyToProcessorTransformer.test.ts @@ -0,0 +1,90 @@ +/* + * Copyright 2024 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 { Entity, EntityPolicy } from '@backstage/catalog-model'; +import { policyToProcessorTransformer } from './policyToProcessorTransformer'; +import { clone } from 'lodash'; + +describe('policyToProcessorTransformer', () => { + const entityToProcess: Entity = { + apiVersion: 'backstage.io/v1alpha', + kind: 'Component', + metadata: { + name: 'test', + }, + }; + it('modifies the entity if the policy modifies the entity', async () => { + const policy: EntityPolicy = { + async enforce(entity) { + entity.kind = 'Group'; + return entity; + }, + }; + const processor = policyToProcessorTransformer(policy); + const clonedEntity = clone(entityToProcess); + const entity = await processor.preProcessEntity?.( + clonedEntity, + {} as any, + jest.fn(), + {} as any, + {} as any, + ); + expect(entity).toBeTruthy(); + expect(entity?.kind).toBe('Group'); + expect(entity?.apiVersion).toBe('backstage.io/v1alpha'); + expect(entity?.metadata.name).toBe('test'); + }); + + it('does not modify the entity if the policy returns undefined', async () => { + const policy: EntityPolicy = { + async enforce() { + return undefined; + }, + }; + const processor = policyToProcessorTransformer(policy); + const clonedEntity = clone(entityToProcess); + const entity = await processor.preProcessEntity?.( + clonedEntity, + {} as any, + jest.fn(), + {} as any, + {} as any, + ); + expect(entity).toBeTruthy(); + expect(entity?.kind).toBe('Component'); + expect(entity?.apiVersion).toBe('backstage.io/v1alpha'); + expect(entity?.metadata.name).toBe('test'); + }); + + it('bubbles up processor error', async () => { + const policy: EntityPolicy = { + async enforce() { + throw new TypeError('Invalid value for metadata.name'); + }, + }; + const processor = policyToProcessorTransformer(policy); + const clonedEntity = clone(entityToProcess); + await expect( + processor.preProcessEntity?.( + clonedEntity, + {} as any, + jest.fn(), + {} as any, + {} as any, + ), + ).rejects.toThrow(/Invalid value for metadata.name/); + }); +}); diff --git a/plugins/catalog-backend/src/modules/core/policyToProcessorTransformer.ts b/plugins/catalog-backend/src/modules/core/policyToProcessorTransformer.ts new file mode 100644 index 0000000000..ba1ce254c7 --- /dev/null +++ b/plugins/catalog-backend/src/modules/core/policyToProcessorTransformer.ts @@ -0,0 +1,41 @@ +/* + * Copyright 2024 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 { EntityPolicy } from '@backstage/catalog-model'; +import { CatalogProcessor } from '@backstage/plugin-catalog-node'; + +/** + * Transform a given entity policy to an entity processor. + * @param policy The policy to transform + * @returns A new entity processor that uses the entity policy. + */ +export function policyToProcessorTransformer( + policy: EntityPolicy, +): CatalogProcessor { + return { + getProcessorName() { + return policy.constructor.name; + }, + async preProcessEntity(entity) { + // If enforcing the policy fails, throw the policy error. + const result = await policy.enforce(entity); + if (!result) { + return entity; + } + return result; + }, + }; +} From 447d8b6fcf6ee080001643292df0c13f56de3b06 Mon Sep 17 00:00:00 2001 From: Aramis Date: Fri, 2 Feb 2024 16:42:39 -0500 Subject: [PATCH 04/10] add field validators Signed-off-by: Aramis --- .../src/service/CatalogPlugin.ts | 27 +++++++------------ plugins/catalog-node/src/extensions.ts | 15 +++++++++-- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/plugins/catalog-backend/src/service/CatalogPlugin.ts b/plugins/catalog-backend/src/service/CatalogPlugin.ts index 5bcaaba1fb..1fca11e482 100644 --- a/plugins/catalog-backend/src/service/CatalogPlugin.ts +++ b/plugins/catalog-backend/src/service/CatalogPlugin.ts @@ -17,7 +17,7 @@ import { createBackendPlugin, coreServices, } from '@backstage/backend-plugin-api'; -import { Entity, EntityPolicy } from '@backstage/catalog-model'; +import { Entity, EntityPolicy, Validators } from '@backstage/catalog-model'; import { CatalogBuilder, CatalogPermissionRuleInput } from './CatalogBuilder'; import { CatalogAnalysisExtensionPoint, @@ -36,6 +36,7 @@ import { ScmLocationAnalyzer, } from '@backstage/plugin-catalog-node'; import { loggerToWinstonLogger } from '@backstage/backend-common'; +import { merge } from 'lodash'; class CatalogProcessingExtensionPointImpl implements CatalogProcessingExtensionPoint @@ -128,28 +129,22 @@ class CatalogPermissionExtensionPointImpl class CatalogModelExtensionPointImpl implements CatalogModelExtensionPoint { #entityPolicies = new Array(); - #replaced = false; + #fieldValidators: Partial = {}; addEntityPolicies(...policies: Array>) { this.#entityPolicies.push(...policies.flat()); } - replaceEntityPolicies(...policies: Array) { - if (this.#replaced) { - throw new Error( - `You've already replaced the entity policies. If you want to add more entity policies, see 'addEntityPolicies'.`, - ); - } - this.#entityPolicies = [...policies]; - this.#replaced = true; + setFieldValidators(validators: Partial): void { + merge(this.#fieldValidators, validators); } get entityPolicies() { return this.#entityPolicies; } - get replaced() { - return this.#replaced; + get fieldValidators() { + return this.#fieldValidators; } } @@ -224,12 +219,8 @@ export const catalogPlugin = createBackendPlugin({ ); builder.addLocationAnalyzers(...analysisExtensions.locationAnalyzers); builder.addPermissionRules(...permissionExtensions.permissionRules); - - if (modelExtensions.replaced) { - builder.replaceEntityPolicies(modelExtensions.entityPolicies); - } else { - builder.addEntityPolicy(...modelExtensions.entityPolicies); - } + builder.addEntityPolicy(...modelExtensions.entityPolicies); + builder.setFieldFormatValidators(modelExtensions.fieldValidators); const { processingEngine, router } = await builder.build(); diff --git a/plugins/catalog-node/src/extensions.ts b/plugins/catalog-node/src/extensions.ts index 7c63e51c69..004a46445e 100644 --- a/plugins/catalog-node/src/extensions.ts +++ b/plugins/catalog-node/src/extensions.ts @@ -15,7 +15,7 @@ */ import { createExtensionPoint } from '@backstage/backend-plugin-api'; -import { Entity, EntityPolicy } from '@backstage/catalog-model'; +import { Entity, EntityPolicy, Validators } from '@backstage/catalog-model'; import { CatalogProcessor, EntitiesSearchFilter, @@ -47,11 +47,22 @@ export interface CatalogProcessingExtensionPoint { /** @alpha */ export interface CatalogModelExtensionPoint { + /** + * @deprecated Use `policyToProcessorTransformer` from `@backstage/plugin-catalog-backend` + * and `CatalogProcessingExtensionPoint.addProcessor` instead. + */ addEntityPolicies( ...policies: Array> ): void; - replaceEntityPolicies(...policies: Array): void; + /** + * Sets the validator function to use for one or more special fields of an + * entity. This is useful if the default rules for formatting of fields are + * not sufficient. + * + * @param validators - The (subset of) validators to set + */ + setFieldValidators(validators: Partial): void; } /** From af751400d679474aae497623075e973f479aa7c2 Mon Sep 17 00:00:00 2001 From: Aramis Date: Fri, 2 Feb 2024 16:42:47 -0500 Subject: [PATCH 05/10] fix api report Signed-off-by: Aramis Signed-off-by: aramissennyeydd --- plugins/catalog-backend/api-report.md | 5 +++++ plugins/catalog-backend/src/modules/core/index.ts | 1 + .../src/modules/core/policyToProcessorTransformer.ts | 3 ++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/plugins/catalog-backend/api-report.md b/plugins/catalog-backend/api-report.md index a38a964d48..e00436846a 100644 --- a/plugins/catalog-backend/api-report.md +++ b/plugins/catalog-backend/api-report.md @@ -421,6 +421,11 @@ export type PlaceholderResolverRead = PlaceholderResolverRead_2; // @public @deprecated (undocumented) export type PlaceholderResolverResolveUrl = PlaceholderResolverResolveUrl_2; +// @public +export function policyToProcessorTransformer( + policy: EntityPolicy, +): CatalogProcessor_2; + // @public export type ProcessingIntervalFunction = () => number; diff --git a/plugins/catalog-backend/src/modules/core/index.ts b/plugins/catalog-backend/src/modules/core/index.ts index 365def0bfe..54f16c99b1 100644 --- a/plugins/catalog-backend/src/modules/core/index.ts +++ b/plugins/catalog-backend/src/modules/core/index.ts @@ -24,3 +24,4 @@ export { PlaceholderProcessor } from './PlaceholderProcessor'; export type { PlaceholderProcessorOptions } from './PlaceholderProcessor'; export { UrlReaderProcessor } from './UrlReaderProcessor'; export { parseEntityYaml } from '../util/parse'; +export { policyToProcessorTransformer } from './policyToProcessorTransformer'; diff --git a/plugins/catalog-backend/src/modules/core/policyToProcessorTransformer.ts b/plugins/catalog-backend/src/modules/core/policyToProcessorTransformer.ts index ba1ce254c7..69b2788779 100644 --- a/plugins/catalog-backend/src/modules/core/policyToProcessorTransformer.ts +++ b/plugins/catalog-backend/src/modules/core/policyToProcessorTransformer.ts @@ -19,8 +19,9 @@ import { CatalogProcessor } from '@backstage/plugin-catalog-node'; /** * Transform a given entity policy to an entity processor. - * @param policy The policy to transform + * @param policy - The policy to transform * @returns A new entity processor that uses the entity policy. + * @public */ export function policyToProcessorTransformer( policy: EntityPolicy, From 9281ab3bb6c94417d1dbc6ece6f1a167e447be44 Mon Sep 17 00:00:00 2001 From: Aramis Date: Fri, 2 Feb 2024 16:53:57 -0500 Subject: [PATCH 06/10] fix api reports Signed-off-by: Aramis Signed-off-by: aramissennyeydd --- plugins/catalog-node/api-report-alpha.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/catalog-node/api-report-alpha.md b/plugins/catalog-node/api-report-alpha.md index 64382e56bb..9243fa98fe 100644 --- a/plugins/catalog-node/api-report-alpha.md +++ b/plugins/catalog-node/api-report-alpha.md @@ -15,6 +15,7 @@ import { PermissionRuleParams } from '@backstage/plugin-permission-common'; import { PlaceholderResolver } from '@backstage/plugin-catalog-node'; import { ScmLocationAnalyzer } from '@backstage/plugin-catalog-node'; import { ServiceRef } from '@backstage/backend-plugin-api'; +import { Validators } from '@backstage/catalog-model'; // @alpha (undocumented) export interface CatalogAnalysisExtensionPoint { @@ -27,12 +28,11 @@ export const catalogAnalysisExtensionPoint: ExtensionPoint> ): void; - // (undocumented) - replaceEntityPolicies(...policies: Array): void; + setFieldValidators(validators: Partial): void; } // @alpha (undocumented) From 28a0882dbbe7c48d92649f3324f3321564109d0a Mon Sep 17 00:00:00 2001 From: Aramis Date: Mon, 12 Feb 2024 08:38:48 -0500 Subject: [PATCH 07/10] rename to transformLegacyPolicyToProcessor Signed-off-by: Aramis Signed-off-by: aramissennyeydd --- plugins/catalog-backend/api-report.md | 10 +++++----- plugins/catalog-backend/src/modules/core/index.ts | 2 +- ...est.ts => transformLegacyPolicyToProcessor.test.ts} | 10 +++++----- ...nsformer.ts => transformLegacyPolicyToProcessor.ts} | 2 +- plugins/catalog-node/src/extensions.ts | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) rename plugins/catalog-backend/src/modules/core/{policyToProcessorTransformer.test.ts => transformLegacyPolicyToProcessor.test.ts} (88%) rename plugins/catalog-backend/src/modules/core/{policyToProcessorTransformer.ts => transformLegacyPolicyToProcessor.ts} (96%) diff --git a/plugins/catalog-backend/api-report.md b/plugins/catalog-backend/api-report.md index e00436846a..92a2fbb280 100644 --- a/plugins/catalog-backend/api-report.md +++ b/plugins/catalog-backend/api-report.md @@ -421,11 +421,6 @@ export type PlaceholderResolverRead = PlaceholderResolverRead_2; // @public @deprecated (undocumented) export type PlaceholderResolverResolveUrl = PlaceholderResolverResolveUrl_2; -// @public -export function policyToProcessorTransformer( - policy: EntityPolicy, -): CatalogProcessor_2; - // @public export type ProcessingIntervalFunction = () => number; @@ -455,6 +450,11 @@ export const processingResult: Readonly<{ // @public @deprecated (undocumented) export type ScmLocationAnalyzer = ScmLocationAnalyzer_2; +// @public +export function transformLegacyPolicyToProcessor( + policy: EntityPolicy, +): CatalogProcessor_2; + // @public (undocumented) export class UrlReaderProcessor implements CatalogProcessor_2 { constructor(options: { reader: UrlReader; logger: Logger }); diff --git a/plugins/catalog-backend/src/modules/core/index.ts b/plugins/catalog-backend/src/modules/core/index.ts index 54f16c99b1..e410c3824d 100644 --- a/plugins/catalog-backend/src/modules/core/index.ts +++ b/plugins/catalog-backend/src/modules/core/index.ts @@ -24,4 +24,4 @@ export { PlaceholderProcessor } from './PlaceholderProcessor'; export type { PlaceholderProcessorOptions } from './PlaceholderProcessor'; export { UrlReaderProcessor } from './UrlReaderProcessor'; export { parseEntityYaml } from '../util/parse'; -export { policyToProcessorTransformer } from './policyToProcessorTransformer'; +export { transformLegacyPolicyToProcessor } from './transformLegacyPolicyToProcessor'; diff --git a/plugins/catalog-backend/src/modules/core/policyToProcessorTransformer.test.ts b/plugins/catalog-backend/src/modules/core/transformLegacyPolicyToProcessor.test.ts similarity index 88% rename from plugins/catalog-backend/src/modules/core/policyToProcessorTransformer.test.ts rename to plugins/catalog-backend/src/modules/core/transformLegacyPolicyToProcessor.test.ts index 46338ce6cb..a38074723c 100644 --- a/plugins/catalog-backend/src/modules/core/policyToProcessorTransformer.test.ts +++ b/plugins/catalog-backend/src/modules/core/transformLegacyPolicyToProcessor.test.ts @@ -15,10 +15,10 @@ */ import { Entity, EntityPolicy } from '@backstage/catalog-model'; -import { policyToProcessorTransformer } from './policyToProcessorTransformer'; +import { transformLegacyPolicyToProcessor } from './transformLegacyPolicyToProcessor'; import { clone } from 'lodash'; -describe('policyToProcessorTransformer', () => { +describe('transformLegacyPolicyToProcessor', () => { const entityToProcess: Entity = { apiVersion: 'backstage.io/v1alpha', kind: 'Component', @@ -33,7 +33,7 @@ describe('policyToProcessorTransformer', () => { return entity; }, }; - const processor = policyToProcessorTransformer(policy); + const processor = transformLegacyPolicyToProcessor(policy); const clonedEntity = clone(entityToProcess); const entity = await processor.preProcessEntity?.( clonedEntity, @@ -54,7 +54,7 @@ describe('policyToProcessorTransformer', () => { return undefined; }, }; - const processor = policyToProcessorTransformer(policy); + const processor = transformLegacyPolicyToProcessor(policy); const clonedEntity = clone(entityToProcess); const entity = await processor.preProcessEntity?.( clonedEntity, @@ -75,7 +75,7 @@ describe('policyToProcessorTransformer', () => { throw new TypeError('Invalid value for metadata.name'); }, }; - const processor = policyToProcessorTransformer(policy); + const processor = transformLegacyPolicyToProcessor(policy); const clonedEntity = clone(entityToProcess); await expect( processor.preProcessEntity?.( diff --git a/plugins/catalog-backend/src/modules/core/policyToProcessorTransformer.ts b/plugins/catalog-backend/src/modules/core/transformLegacyPolicyToProcessor.ts similarity index 96% rename from plugins/catalog-backend/src/modules/core/policyToProcessorTransformer.ts rename to plugins/catalog-backend/src/modules/core/transformLegacyPolicyToProcessor.ts index 69b2788779..40a3e749ab 100644 --- a/plugins/catalog-backend/src/modules/core/policyToProcessorTransformer.ts +++ b/plugins/catalog-backend/src/modules/core/transformLegacyPolicyToProcessor.ts @@ -23,7 +23,7 @@ import { CatalogProcessor } from '@backstage/plugin-catalog-node'; * @returns A new entity processor that uses the entity policy. * @public */ -export function policyToProcessorTransformer( +export function transformLegacyPolicyToProcessor( policy: EntityPolicy, ): CatalogProcessor { return { diff --git a/plugins/catalog-node/src/extensions.ts b/plugins/catalog-node/src/extensions.ts index 004a46445e..df1b8b0d57 100644 --- a/plugins/catalog-node/src/extensions.ts +++ b/plugins/catalog-node/src/extensions.ts @@ -48,7 +48,7 @@ export interface CatalogProcessingExtensionPoint { /** @alpha */ export interface CatalogModelExtensionPoint { /** - * @deprecated Use `policyToProcessorTransformer` from `@backstage/plugin-catalog-backend` + * @deprecated Use `transformLegacyPolicyToProcessor` from `@backstage/plugin-catalog-backend` * and `CatalogProcessingExtensionPoint.addProcessor` instead. */ addEntityPolicies( From 0eda4bc6299a2110d2b32016a1d5326a4f2d5c7f Mon Sep 17 00:00:00 2001 From: Aramis Date: Mon, 12 Feb 2024 08:50:00 -0500 Subject: [PATCH 08/10] remove support for adding entity policies entirely Signed-off-by: Aramis --- .changeset/thirty-bags-try.md | 29 ++++++++++++++++++- .../src/service/CatalogPlugin.ts | 10 ------- plugins/catalog-node/src/extensions.ts | 10 +------ 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/.changeset/thirty-bags-try.md b/.changeset/thirty-bags-try.md index 7a8156e44c..f04d0160bf 100644 --- a/.changeset/thirty-bags-try.md +++ b/.changeset/thirty-bags-try.md @@ -2,4 +2,31 @@ '@backstage/plugin-catalog-backend': minor --- -Add support for defining entity policies in the new backend. +Adds support for supplying field validators to the new backend's catalog plugin. If you're using entity policies, you should use the new `transformLegacyPolicyToProcessor` function to install them as processors instead. + +```ts +import { + catalogProcessingExtensionPoint, + catalogModelExtensionPoint, +} from '@backstage/plugin-catalog-node/alpha'; +import {myPolicy} from './my-policy'; + +export const catalogModulePolicyProvider = createBackendModule({ + pluginId: 'catalog', + moduleId: 'internal-policy-provider', + register(reg) { + reg.registerInit({ + deps: { + modelExtensions: catalogModelExtensionPoint, + processingExtensions: catalogProcessingExtensionPoint, + }, + async init({ modelExtensions, processingExtensions }) { + modelExtensions.setFieldValidators({ + ... + }); + processingExtensions.addProcessors(transformLegacyPolicyToProcessor(myPolicy)) + }, + }); + }, +}); +``` diff --git a/plugins/catalog-backend/src/service/CatalogPlugin.ts b/plugins/catalog-backend/src/service/CatalogPlugin.ts index 1fca11e482..114dbe6f61 100644 --- a/plugins/catalog-backend/src/service/CatalogPlugin.ts +++ b/plugins/catalog-backend/src/service/CatalogPlugin.ts @@ -128,21 +128,12 @@ class CatalogPermissionExtensionPointImpl } class CatalogModelExtensionPointImpl implements CatalogModelExtensionPoint { - #entityPolicies = new Array(); #fieldValidators: Partial = {}; - addEntityPolicies(...policies: Array>) { - this.#entityPolicies.push(...policies.flat()); - } - setFieldValidators(validators: Partial): void { merge(this.#fieldValidators, validators); } - get entityPolicies() { - return this.#entityPolicies; - } - get fieldValidators() { return this.#fieldValidators; } @@ -219,7 +210,6 @@ export const catalogPlugin = createBackendPlugin({ ); builder.addLocationAnalyzers(...analysisExtensions.locationAnalyzers); builder.addPermissionRules(...permissionExtensions.permissionRules); - builder.addEntityPolicy(...modelExtensions.entityPolicies); builder.setFieldFormatValidators(modelExtensions.fieldValidators); const { processingEngine, router } = await builder.build(); diff --git a/plugins/catalog-node/src/extensions.ts b/plugins/catalog-node/src/extensions.ts index df1b8b0d57..763e934176 100644 --- a/plugins/catalog-node/src/extensions.ts +++ b/plugins/catalog-node/src/extensions.ts @@ -15,7 +15,7 @@ */ import { createExtensionPoint } from '@backstage/backend-plugin-api'; -import { Entity, EntityPolicy, Validators } from '@backstage/catalog-model'; +import { Entity, Validators } from '@backstage/catalog-model'; import { CatalogProcessor, EntitiesSearchFilter, @@ -47,14 +47,6 @@ export interface CatalogProcessingExtensionPoint { /** @alpha */ export interface CatalogModelExtensionPoint { - /** - * @deprecated Use `transformLegacyPolicyToProcessor` from `@backstage/plugin-catalog-backend` - * and `CatalogProcessingExtensionPoint.addProcessor` instead. - */ - addEntityPolicies( - ...policies: Array> - ): void; - /** * Sets the validator function to use for one or more special fields of an * entity. This is useful if the default rules for formatting of fields are From 3d1954f80dae8f4ae327ae0813177dc0363731f0 Mon Sep 17 00:00:00 2001 From: Aramis Date: Mon, 12 Feb 2024 09:34:33 -0500 Subject: [PATCH 09/10] fix api report Signed-off-by: Aramis Signed-off-by: aramissennyeydd --- plugins/catalog-node/api-report-alpha.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/plugins/catalog-node/api-report-alpha.md b/plugins/catalog-node/api-report-alpha.md index 9243fa98fe..e43d1bd49f 100644 --- a/plugins/catalog-node/api-report-alpha.md +++ b/plugins/catalog-node/api-report-alpha.md @@ -7,7 +7,6 @@ import { CatalogApi } from '@backstage/catalog-client'; import { CatalogProcessor } from '@backstage/plugin-catalog-node'; import { EntitiesSearchFilter } from '@backstage/plugin-catalog-node'; import { Entity } from '@backstage/catalog-model'; -import { EntityPolicy } from '@backstage/catalog-model'; import { EntityProvider } from '@backstage/plugin-catalog-node'; import { ExtensionPoint } from '@backstage/backend-plugin-api'; import { PermissionRule } from '@backstage/plugin-permission-node'; @@ -28,10 +27,6 @@ export const catalogAnalysisExtensionPoint: ExtensionPoint> - ): void; setFieldValidators(validators: Partial): void; } From 5182f5bfdde84756b3d87de0765525ce8d2689c2 Mon Sep 17 00:00:00 2001 From: aramissennyeydd Date: Fri, 16 Feb 2024 19:51:51 -0500 Subject: [PATCH 10/10] merge fixes and update changeset Signed-off-by: aramissennyeydd --- .changeset/thirty-bags-try.md | 1 + plugins/catalog-backend/src/service/CatalogPlugin.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.changeset/thirty-bags-try.md b/.changeset/thirty-bags-try.md index f04d0160bf..98d6c5620b 100644 --- a/.changeset/thirty-bags-try.md +++ b/.changeset/thirty-bags-try.md @@ -1,5 +1,6 @@ --- '@backstage/plugin-catalog-backend': minor +'@backstage/plugin-catalog-node': minor --- Adds support for supplying field validators to the new backend's catalog plugin. If you're using entity policies, you should use the new `transformLegacyPolicyToProcessor` function to install them as processors instead. diff --git a/plugins/catalog-backend/src/service/CatalogPlugin.ts b/plugins/catalog-backend/src/service/CatalogPlugin.ts index 114dbe6f61..255df84d58 100644 --- a/plugins/catalog-backend/src/service/CatalogPlugin.ts +++ b/plugins/catalog-backend/src/service/CatalogPlugin.ts @@ -17,7 +17,7 @@ import { createBackendPlugin, coreServices, } from '@backstage/backend-plugin-api'; -import { Entity, EntityPolicy, Validators } from '@backstage/catalog-model'; +import { Entity, Validators } from '@backstage/catalog-model'; import { CatalogBuilder, CatalogPermissionRuleInput } from './CatalogBuilder'; import { CatalogAnalysisExtensionPoint,