From d4a3dbb75b448137cda3578b7c90e99f4e3b2f89 Mon Sep 17 00:00:00 2001 From: Iain Billett Date: Mon, 15 Nov 2021 18:27:48 +0000 Subject: [PATCH] Expose catalogFactRetriever & configure in backend Signed-off-by: Iain Billett --- packages/backend/src/plugins/techInsights.ts | 41 +++---------------- plugins/tech-insights-backend/src/index.ts | 1 + ...r.test.ts => catalogFactRetriever.test.ts} | 6 +-- ...ctRetriever.ts => catalogFactRetriever.ts} | 25 ++++++----- .../src/service/fact/factRetrievers/index.ts | 16 ++++++++ 5 files changed, 40 insertions(+), 49 deletions(-) rename plugins/tech-insights-backend/src/service/fact/factRetrievers/{entityFactRetriever.test.ts => catalogFactRetriever.test.ts} (98%) rename plugins/tech-insights-backend/src/service/fact/factRetrievers/{entityFactRetriever.ts => catalogFactRetriever.ts} (81%) create mode 100644 plugins/tech-insights-backend/src/service/fact/factRetrievers/index.ts diff --git a/packages/backend/src/plugins/techInsights.ts b/packages/backend/src/plugins/techInsights.ts index abab1d133d..6194f03410 100644 --- a/packages/backend/src/plugins/techInsights.ts +++ b/packages/backend/src/plugins/techInsights.ts @@ -17,10 +17,10 @@ import { createRouter, buildTechInsightsContext, createFactRetrieverRegistration, + createCatalogFactRetriever, } from '@backstage/plugin-tech-insights-backend'; import { Router } from 'express'; import { PluginEnvironment } from '../types'; -import { CatalogClient } from '@backstage/catalog-client'; import { JsonRulesEngineFactCheckerFactory, JSON_RULE_ENGINE_CHECK_TYPE, @@ -38,41 +38,10 @@ export default async function createPlugin({ database, discovery, factRetrievers: [ - createFactRetrieverRegistration('5 4 * * 6', { - // Example cron, At 04:05 on Saturday. - id: 'testRetriever', - version: '1.1.2', - entityFilter: [{ kind: 'component' }], // EntityFilter to be used in the future (creating checks, graphs etc.) to figure out which entities this fact retrieves data for. - schema: { - examplenumberfact: { - type: 'integer', - description: 'Example fact returning a number', - }, - }, - handler: async _ctx => { - const catalogClient = new CatalogClient({ - discoveryApi: discovery, - }); - const entities = await catalogClient.getEntities({ - filter: [{ kind: 'component' }], - }); - - return Promise.resolve( - entities.items.map(it => { - return { - entity: { - namespace: it.metadata.namespace!!, - kind: it.kind, - name: it.metadata.name, - }, - facts: { - examplenumberfact: 2, - }, - }; - }), - ); - }, - }), + createFactRetrieverRegistration( + '* * * * *', // Example cron, every minute + createCatalogFactRetriever(), + ), ], factCheckerFactory: new JsonRulesEngineFactCheckerFactory({ checks: [ diff --git a/plugins/tech-insights-backend/src/index.ts b/plugins/tech-insights-backend/src/index.ts index 5e8e690e8d..763c565108 100644 --- a/plugins/tech-insights-backend/src/index.ts +++ b/plugins/tech-insights-backend/src/index.ts @@ -25,3 +25,4 @@ export type { export type { PersistenceContext } from './service/persistence/persistenceContext'; export { createFactRetrieverRegistration } from './service/fact/createFactRetriever'; +export * from './service/fact/factRetrievers'; diff --git a/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityFactRetriever.test.ts b/plugins/tech-insights-backend/src/service/fact/factRetrievers/catalogFactRetriever.test.ts similarity index 98% rename from plugins/tech-insights-backend/src/service/fact/factRetrievers/entityFactRetriever.test.ts rename to plugins/tech-insights-backend/src/service/fact/factRetrievers/catalogFactRetriever.test.ts index a1741c22ee..7b762be63f 100644 --- a/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityFactRetriever.test.ts +++ b/plugins/tech-insights-backend/src/service/fact/factRetrievers/catalogFactRetriever.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { createEntityFactRetriever } from './entityFactRetriever'; +import { createCatalogFactRetriever } from './catalogFactRetriever'; import { Entity, RELATION_OWNED_BY } from '@backstage/catalog-model'; import { PluginEndpointDiscovery, @@ -52,7 +52,7 @@ const defaultEntityListResponse: CatalogListResponse = { spec: { type: 'service', lifecycle: 'test', - owner: 'group:team-a', + owner: 'team-a', }, relations: [ { @@ -106,7 +106,7 @@ const handlerContext = { config: ConfigReader.fromConfigs([]), }; -const entityFactRetriever = createEntityFactRetriever({ +const entityFactRetriever = createCatalogFactRetriever({ annotations: ['backstage.io/techdocs-ref'], }); diff --git a/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityFactRetriever.ts b/plugins/tech-insights-backend/src/service/fact/factRetrievers/catalogFactRetriever.ts similarity index 81% rename from plugins/tech-insights-backend/src/service/fact/factRetrievers/entityFactRetriever.ts rename to plugins/tech-insights-backend/src/service/fact/factRetrievers/catalogFactRetriever.ts index 1442d4d929..d4d6e54865 100644 --- a/plugins/tech-insights-backend/src/service/fact/factRetrievers/entityFactRetriever.ts +++ b/plugins/tech-insights-backend/src/service/fact/factRetrievers/catalogFactRetriever.ts @@ -14,18 +14,23 @@ * limitations under the License. */ -import { FactRetrieverContext } from '@backstage/plugin-tech-insights-node'; +import { + FactRetriever, + FactRetrieverContext, +} from '@backstage/plugin-tech-insights-node'; import { CatalogClient } from '@backstage/catalog-client'; import { Entity } from '@backstage/catalog-model'; import isEmpty from 'lodash/isEmpty'; import camelCase from 'lodash/camelCase'; import { get } from 'lodash'; -export const createEntityFactRetriever = ({ - annotations = [], -}: { +type Options = { annotations?: string[]; -}) => ({ +}; + +export const createCatalogFactRetriever = ( + { annotations = [] }: Options = { annotations: [] }, +): FactRetriever => ({ id: 'entityRetriever', version: '0.0.1', schema: { @@ -39,18 +44,18 @@ export const createEntityFactRetriever = ({ }, hasDescription: { type: 'boolean', - description: 'The entity has an owned_by relation', + description: 'The entity has a description in metadata', }, hasTags: { type: 'boolean', description: 'The entity has tags in metadata', }, - ...annotations.reduce((acc: object, it: string) => { + ...annotations.reduce((acc: object, annotation: string) => { return { ...acc, - [camelCase(`hasAnnotation-${it}`)]: { + [camelCase(`hasAnnotation-${annotation}`)]: { type: 'boolean', - description: `The entity has the annotation: ${it} `, + description: `The entity has the annotation: ${annotation} `, }, }; }, {}), @@ -72,7 +77,7 @@ export const createEntityFactRetriever = ({ hasOwner: Boolean(entity.spec?.owner), hasGroupOwner: Boolean( entity.spec?.owner && - (entity.spec?.owner as string).startsWith('group:'), + !(entity.spec?.owner as string).startsWith('user:'), ), hasDescription: Boolean(entity.metadata?.description), hasTags: !isEmpty(entity.metadata?.tags), diff --git a/plugins/tech-insights-backend/src/service/fact/factRetrievers/index.ts b/plugins/tech-insights-backend/src/service/fact/factRetrievers/index.ts new file mode 100644 index 0000000000..58ee8f8e92 --- /dev/null +++ b/plugins/tech-insights-backend/src/service/fact/factRetrievers/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2021 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 * from './catalogFactRetriever';