From 4a1c318853dc15b98a18db642a2acce0b487d900 Mon Sep 17 00:00:00 2001 From: Niklas Aronsson Date: Fri, 17 Feb 2023 09:54:24 +0100 Subject: [PATCH] Linguist-backend: Add token to catalogClient The catalog client calls will fail for backstage deployments with authentication. Signed-off-by: Niklas Aronsson --- .changeset/nice-planets-wave.md | 5 +++++ plugins/linguist-backend/api-report.md | 4 ++++ .../src/api/LinguistBackendApi.ts | 19 +++++++++++++++---- .../src/service/router.test.ts | 7 +++++++ .../linguist-backend/src/service/router.ts | 6 +++++- .../src/service/standaloneServer.ts | 2 ++ 6 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 .changeset/nice-planets-wave.md diff --git a/.changeset/nice-planets-wave.md b/.changeset/nice-planets-wave.md new file mode 100644 index 0000000000..2af1a14d83 --- /dev/null +++ b/.changeset/nice-planets-wave.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-linguist-backend': minor +--- + +**BREAKING** The linguist-backend `createRouter` now requires that the `tokenManger` is passed to the router. diff --git a/plugins/linguist-backend/api-report.md b/plugins/linguist-backend/api-report.md index c11296b0b3..18fcec978e 100644 --- a/plugins/linguist-backend/api-report.md +++ b/plugins/linguist-backend/api-report.md @@ -14,6 +14,7 @@ import { PluginEndpointDiscovery } from '@backstage/backend-common'; import { PluginTaskScheduler } from '@backstage/backend-tasks'; import { ProcessedEntity } from '@backstage/plugin-linguist-common'; import { TaskScheduleDefinition } from '@backstage/backend-tasks'; +import { TokenManager } from '@backstage/backend-common'; import { UrlReader } from '@backstage/backend-common'; // @public (undocumented) @@ -29,6 +30,7 @@ export class LinguistBackendApi { store: LinguistBackendStore, urlReader: UrlReader, discovery: PluginEndpointDiscovery, + tokenManager: TokenManager, age?: HumanDuration, batchSize?: number, useSourceLocation?: boolean, @@ -96,6 +98,8 @@ export interface RouterOptions { reader: UrlReader; // (undocumented) scheduler?: PluginTaskScheduler; + // (undocumented) + tokenManager: TokenManager; } // (No @packageDocumentation comment for this package) diff --git a/plugins/linguist-backend/src/api/LinguistBackendApi.ts b/plugins/linguist-backend/src/api/LinguistBackendApi.ts index 6c2e46e112..105335b0ed 100644 --- a/plugins/linguist-backend/src/api/LinguistBackendApi.ts +++ b/plugins/linguist-backend/src/api/LinguistBackendApi.ts @@ -25,7 +25,11 @@ import { CatalogClient, GetEntitiesRequest, } from '@backstage/catalog-client'; -import { PluginEndpointDiscovery, UrlReader } from '@backstage/backend-common'; +import { + PluginEndpointDiscovery, + TokenManager, + UrlReader, +} from '@backstage/backend-common'; import { DateTime } from 'luxon'; import { LINGUIST_ANNOTATION } from '@backstage/plugin-linguist-common'; @@ -46,6 +50,8 @@ export class LinguistBackendApi { private readonly store: LinguistBackendStore; private readonly urlReader: UrlReader; private readonly discovery: PluginEndpointDiscovery; + private readonly tokenManager: TokenManager; + private readonly catalogClient: CatalogClient; private readonly age?: HumanDuration; private readonly batchSize?: number; @@ -55,6 +61,7 @@ export class LinguistBackendApi { store: LinguistBackendStore, urlReader: UrlReader, discovery: PluginEndpointDiscovery, + tokenManager: TokenManager, age?: HumanDuration, batchSize?: number, useSourceLocation?: boolean, @@ -63,8 +70,8 @@ export class LinguistBackendApi { this.store = store; this.urlReader = urlReader; this.discovery = discovery; + this.tokenManager = tokenManager; this.catalogClient = new CatalogClient({ discoveryApi: this.discovery }); - this.batchSize = batchSize; this.age = age; this.useSourceLocation = useSourceLocation; @@ -98,7 +105,8 @@ export class LinguistBackendApi { fields: ['kind', 'metadata'], }; - const response = await this.catalogClient.getEntities(request); + const { token } = await this.tokenManager.getToken(); + const response = await this.catalogClient.getEntities(request, { token }); const entities = response.items; entities.forEach(entity => { @@ -118,7 +126,10 @@ export class LinguistBackendApi { this.batchSize ?? 20, ); entities.forEach(async entityRef => { - const entity = await this.catalogClient.getEntityByRef(entityRef); + const { token } = await this.tokenManager.getToken(); + const entity = await this.catalogClient.getEntityByRef(entityRef, { + token, + }); const annotationKey = this.useSourceLocation ? ANNOTATION_SOURCE_LOCATION : LINGUIST_ANNOTATION; diff --git a/plugins/linguist-backend/src/service/router.test.ts b/plugins/linguist-backend/src/service/router.test.ts index 34f16f4b21..b8bde9d35d 100644 --- a/plugins/linguist-backend/src/service/router.test.ts +++ b/plugins/linguist-backend/src/service/router.test.ts @@ -19,6 +19,7 @@ import { getVoidLogger, PluginDatabaseManager, PluginEndpointDiscovery, + TokenManager, UrlReaders, } from '@backstage/backend-common'; import express from 'express'; @@ -48,6 +49,11 @@ const testDiscovery: jest.Mocked = { getExternalBaseUrl: jest.fn(), }; +const mockedTokenManager: jest.Mocked = { + getToken: jest.fn(), + authenticate: jest.fn(), +}; + const mockUrlReader = UrlReaders.default({ logger: getVoidLogger(), config: new ConfigReader({}), @@ -72,6 +78,7 @@ describe('createRouter', () => { database: createDatabase(), reader: mockUrlReader, logger: getVoidLogger(), + tokenManager: mockedTokenManager, }, ); app = express().use(router); diff --git a/plugins/linguist-backend/src/service/router.ts b/plugins/linguist-backend/src/service/router.ts index e3aeec604e..18c43d996a 100644 --- a/plugins/linguist-backend/src/service/router.ts +++ b/plugins/linguist-backend/src/service/router.ts @@ -18,6 +18,7 @@ import { errorHandler, PluginDatabaseManager, PluginEndpointDiscovery, + TokenManager, UrlReader, } from '@backstage/backend-common'; import express from 'express'; @@ -44,6 +45,7 @@ export interface RouterOptions { linguistBackendApi?: LinguistBackendApi; logger: Logger; reader: UrlReader; + tokenManager: TokenManager; database: PluginDatabaseManager; discovery: PluginEndpointDiscovery; scheduler?: PluginTaskScheduler; @@ -56,7 +58,8 @@ export async function createRouter( ): Promise { const { schedule, age, batchSize, useSourceLocation } = pluginOptions; - const { logger, reader, database, discovery, scheduler } = routerOptions; + const { logger, reader, database, discovery, scheduler, tokenManager } = + routerOptions; const linguistBackendStore = await LinguistBackendDatabase.create( await database.getClient(), @@ -69,6 +72,7 @@ export async function createRouter( linguistBackendStore, reader, discovery, + tokenManager, age, batchSize, useSourceLocation, diff --git a/plugins/linguist-backend/src/service/standaloneServer.ts b/plugins/linguist-backend/src/service/standaloneServer.ts index 828c83630a..11604cddfb 100644 --- a/plugins/linguist-backend/src/service/standaloneServer.ts +++ b/plugins/linguist-backend/src/service/standaloneServer.ts @@ -20,6 +20,7 @@ import { SingleHostDiscovery, UrlReaders, useHotMemoize, + ServerTokenManager, } from '@backstage/backend-common'; import { Server } from 'http'; import { Logger } from 'winston'; @@ -66,6 +67,7 @@ export async function startStandaloneServer( discovery: SingleHostDiscovery.fromConfig(config), reader: UrlReaders.default({ logger, config }), logger, + tokenManager: ServerTokenManager.noop(), }, );