From 53eb5e61e31ed470d5c8acf5c33328aeae1c9198 Mon Sep 17 00:00:00 2001 From: Marvin9 Date: Tue, 13 Oct 2020 19:13:05 +0530 Subject: [PATCH 01/12] feat: Implement CatalogEntityClient, mainly to get Template entity from template name --- .../src/lib/catalog/CatalogEntityClient.ts | 70 +++++++++++++++++++ .../src/lib/catalog/index.ts | 16 +++++ 2 files changed, 86 insertions(+) create mode 100644 plugins/scaffolder-backend/src/lib/catalog/CatalogEntityClient.ts create mode 100644 plugins/scaffolder-backend/src/lib/catalog/index.ts diff --git a/plugins/scaffolder-backend/src/lib/catalog/CatalogEntityClient.ts b/plugins/scaffolder-backend/src/lib/catalog/CatalogEntityClient.ts new file mode 100644 index 0000000000..48856e7783 --- /dev/null +++ b/plugins/scaffolder-backend/src/lib/catalog/CatalogEntityClient.ts @@ -0,0 +1,70 @@ +/* + * Copyright 2020 Spotify AB + * + * 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 fetch from 'node-fetch'; +import { TemplateEntityV1alpha1 } from '@backstage/catalog-model'; +import { + ConflictError, + NotFoundError, + PluginEndpointDiscovery, +} from '@backstage/backend-common'; + +/** + * A catalog client tailored for reading out entity data from the catalog. + */ +export class CatalogEntityClient { + private readonly discovery: PluginEndpointDiscovery; + + constructor(options: { discovery: PluginEndpointDiscovery }) { + this.discovery = options.discovery; + } + + /** + * Looks up a single template using a template name. + * + * Throws a NotFoundError or ConflictError if 0 or multiple templates are found. + */ + async findTemplate(templateName: string): Promise { + const params = new URLSearchParams(); + params.append('kind', 'Template'); + + params.append('metadata.name', templateName); + + const baseUrl = await this.discovery.getBaseUrl('catalog'); + const response = await fetch(`${baseUrl}/entities?${params}`); + + if (!response.ok) { + const text = await response.text(); + throw new Error( + `Request failed with ${response.status} ${response.statusText}, ${text}`, + ); + } + + const templates: TemplateEntityV1alpha1[] = await response.json(); + + if (templates.length !== 1) { + if (templates.length > 1) { + throw new ConflictError( + 'Templates lookup resulted in multiple matches', + ); + } else { + throw new NotFoundError('Template not found'); + } + } + + return templates[0]; + } +} diff --git a/plugins/scaffolder-backend/src/lib/catalog/index.ts b/plugins/scaffolder-backend/src/lib/catalog/index.ts new file mode 100644 index 0000000000..a8de546e00 --- /dev/null +++ b/plugins/scaffolder-backend/src/lib/catalog/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2020 Spotify AB + * + * 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 { CatalogEntityClient } from './CatalogEntityClient'; From a24b6577212edb80009ac79b8121de12a86278b5 Mon Sep 17 00:00:00 2001 From: Marvin9 Date: Tue, 13 Oct 2020 19:14:49 +0530 Subject: [PATCH 02/12] feat: use CatalogEntityClient --- plugins/scaffolder-backend/package.json | 3 ++- .../scaffolder-backend/src/service/router.ts | 23 +++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index 66d6457333..fac30df196 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -44,7 +44,8 @@ "nodegit": "0.27.0", "uuid": "^8.2.0", "winston": "^3.2.1", - "yaml": "^1.10.0" + "yaml": "^1.10.0", + "node-fetch": "^2.6.1" }, "devDependencies": { "@backstage/cli": "^0.1.1-alpha.25", diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index f61d2566b9..a556916df0 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -14,8 +14,12 @@ * limitations under the License. */ +import { + loadBackendConfig, + SingleHostDiscovery, +} from '@backstage/backend-common'; +import { JsonValue, ConfigReader } from '@backstage/config'; import { TemplateEntityV1alpha1 } from '@backstage/catalog-model'; -import { JsonValue } from '@backstage/config'; import Docker from 'dockerode'; import express from 'express'; import Router from 'express-promise-router'; @@ -28,6 +32,7 @@ import { TemplaterBuilder, PublisherBuilder, } from '../scaffolder'; +import { CatalogEntityClient } from '../lib/catalog'; import { validate, ValidatorResult } from 'jsonschema'; export interface RouterOptions { @@ -56,6 +61,10 @@ export async function createRouter( const logger = parentLogger.child({ plugin: 'scaffolder' }); const jobProcessor = new JobProcessor(); + const config = ConfigReader.fromConfigs(await loadBackendConfig()); + const discovery = SingleHostDiscovery.fromConfig(config); + const entityClient = new CatalogEntityClient({ discovery }); + router .get('/v1/job/:jobId', ({ params }, res) => { const job = jobProcessor.get(params.jobId); @@ -81,14 +90,24 @@ export async function createRouter( }); }) .post('/v1/jobs', async (req, res) => { - const template: TemplateEntityV1alpha1 = req.body.template; + const templateName: string = req.body.templateName; const values: RequiredTemplateValues & Record = req.body.values; + let template: TemplateEntityV1alpha1; + try { + template = await entityClient.findTemplate(templateName); + } catch (e) { + // help me here + res.status(400).json({ errors: e }); + return; + } + const validationResult: ValidatorResult = validate( values, template.spec.schema, ); + if (!validationResult.valid) { res.status(400).json({ errors: validationResult.errors }); return; From 91e425fdabb5a024d81114ab643655422e71fb38 Mon Sep 17 00:00:00 2001 From: Marvin9 Date: Tue, 13 Oct 2020 19:16:22 +0530 Subject: [PATCH 03/12] feat: Pass entity unique id to POST body of /v1/jobs instead of entire entity --- plugins/scaffolder/src/api.ts | 10 +++------- .../src/components/TemplatePage/TemplatePage.tsx | 2 +- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/plugins/scaffolder/src/api.ts b/plugins/scaffolder/src/api.ts index f58c8e68d1..ca52418e92 100644 --- a/plugins/scaffolder/src/api.ts +++ b/plugins/scaffolder/src/api.ts @@ -15,7 +15,6 @@ */ import { createApiRef, DiscoveryApi } from '@backstage/core'; -import { TemplateEntityV1alpha1 } from '@backstage/catalog-model'; export const scaffolderApiRef = createApiRef({ id: 'plugin.scaffolder.service', @@ -33,20 +32,17 @@ export class ScaffolderApi { * Executes the scaffolding of a component, given a template and its * parameter values. * - * @param template Template entity for the scaffolder to use. New project is going to be created out of this template. + * @param templateName Template name for the scaffolder to use. New project is going to be created out of this template. * @param values Parameters for the template, e.g. name, description */ - async scaffold( - template: TemplateEntityV1alpha1, - values: Record, - ) { + async scaffold(templateName: string, values: Record) { const url = `${await this.discoveryApi.getBaseUrl('scaffolder')}/v1/jobs`; const response = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json', }, - body: JSON.stringify({ template, values: { ...values } }), + body: JSON.stringify({ templateName, values: { ...values } }), }); if (response.status !== 201) { diff --git a/plugins/scaffolder/src/components/TemplatePage/TemplatePage.tsx b/plugins/scaffolder/src/components/TemplatePage/TemplatePage.tsx index e68c795bd6..6c71a2eab1 100644 --- a/plugins/scaffolder/src/components/TemplatePage/TemplatePage.tsx +++ b/plugins/scaffolder/src/components/TemplatePage/TemplatePage.tsx @@ -97,7 +97,7 @@ export const TemplatePage = () => { const handleCreate = async () => { try { - const job = await scaffolderApi.scaffold(template!, formState); + const job = await scaffolderApi.scaffold(templateName, formState); setJobId(job); } catch (e) { errorApi.post(e); From c5acbbb8c42114338747935d7c044898f6578bd0 Mon Sep 17 00:00:00 2001 From: Marvin9 Date: Fri, 23 Oct 2020 23:32:10 +0530 Subject: [PATCH 04/12] chore: replace node-fetch => cross-fetch --- plugins/scaffolder-backend/package.json | 2 +- .../scaffolder-backend/src/lib/catalog/CatalogEntityClient.ts | 2 +- yarn.lock | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/scaffolder-backend/package.json b/plugins/scaffolder-backend/package.json index fac30df196..e87f86961e 100644 --- a/plugins/scaffolder-backend/package.json +++ b/plugins/scaffolder-backend/package.json @@ -45,7 +45,7 @@ "uuid": "^8.2.0", "winston": "^3.2.1", "yaml": "^1.10.0", - "node-fetch": "^2.6.1" + "cross-fetch": "^3.0.6" }, "devDependencies": { "@backstage/cli": "^0.1.1-alpha.25", diff --git a/plugins/scaffolder-backend/src/lib/catalog/CatalogEntityClient.ts b/plugins/scaffolder-backend/src/lib/catalog/CatalogEntityClient.ts index 48856e7783..84676b63fe 100644 --- a/plugins/scaffolder-backend/src/lib/catalog/CatalogEntityClient.ts +++ b/plugins/scaffolder-backend/src/lib/catalog/CatalogEntityClient.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import fetch from 'node-fetch'; +import fetch from 'cross-fetch'; import { TemplateEntityV1alpha1 } from '@backstage/catalog-model'; import { ConflictError, diff --git a/yarn.lock b/yarn.lock index 4832a549b8..2c7c609835 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9021,7 +9021,7 @@ cross-env@^7.0.0: dependencies: cross-spawn "^7.0.1" -cross-fetch@3.0.6, cross-fetch@^3.0.4, cross-fetch@^3.0.5: +cross-fetch@3.0.6, cross-fetch@^3.0.4, cross-fetch@^3.0.5, cross-fetch@^3.0.6: version "3.0.6" resolved "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.0.6.tgz#3a4040bc8941e653e0e9cf17f29ebcd177d3365c" integrity sha512-KBPUbqgFjzWlVcURG+Svp9TlhA5uliYtiNx/0r8nv0pdypeQCRJ9IaSIc3q/x3q8t3F75cHuwxVql1HFGHCNJQ== From 8440f8f91be240cf96c7447262547adb653ba410 Mon Sep 17 00:00:00 2001 From: Marvin9 Date: Tue, 27 Oct 2020 10:02:56 +0530 Subject: [PATCH 05/12] feat: load config directly, #2976 --- plugins/scaffolder-backend/src/service/router.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index a556916df0..bf1eeae8dd 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -17,8 +17,9 @@ import { loadBackendConfig, SingleHostDiscovery, + getRootLogger, } from '@backstage/backend-common'; -import { JsonValue, ConfigReader } from '@backstage/config'; +import { JsonValue } from '@backstage/config'; import { TemplateEntityV1alpha1 } from '@backstage/catalog-model'; import Docker from 'dockerode'; import express from 'express'; @@ -61,7 +62,10 @@ export async function createRouter( const logger = parentLogger.child({ plugin: 'scaffolder' }); const jobProcessor = new JobProcessor(); - const config = ConfigReader.fromConfigs(await loadBackendConfig()); + const config = await loadBackendConfig({ + argv: process.argv, + logger: getRootLogger(), + }); const discovery = SingleHostDiscovery.fromConfig(config); const entityClient = new CatalogEntityClient({ discovery }); From f2a9bba5e27ad2e2ec29d3fdccec303d8de1e808 Mon Sep 17 00:00:00 2001 From: Marvin9 Date: Tue, 27 Oct 2020 10:53:40 +0530 Subject: [PATCH 06/12] feat: update related to #3066 --- .../src/lib/catalog/CatalogEntityClient.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/plugins/scaffolder-backend/src/lib/catalog/CatalogEntityClient.ts b/plugins/scaffolder-backend/src/lib/catalog/CatalogEntityClient.ts index 84676b63fe..4541f03a4a 100644 --- a/plugins/scaffolder-backend/src/lib/catalog/CatalogEntityClient.ts +++ b/plugins/scaffolder-backend/src/lib/catalog/CatalogEntityClient.ts @@ -38,13 +38,15 @@ export class CatalogEntityClient { * Throws a NotFoundError or ConflictError if 0 or multiple templates are found. */ async findTemplate(templateName: string): Promise { - const params = new URLSearchParams(); - params.append('kind', 'Template'); - - params.append('metadata.name', templateName); + const conditions = [ + 'kind=template', + `metadata.name=${encodeURIComponent(templateName)}`, + ]; const baseUrl = await this.discovery.getBaseUrl('catalog'); - const response = await fetch(`${baseUrl}/entities?${params}`); + const response = await fetch( + `${baseUrl}/entities?filter=${conditions.join(',')}`, + ); if (!response.ok) { const text = await response.text(); From 097e3d222a61889c029c109d9693f8ec298ada0d Mon Sep 17 00:00:00 2001 From: Marvin9 Date: Wed, 28 Oct 2020 10:54:38 +0530 Subject: [PATCH 07/12] fix: error handling --- plugins/scaffolder-backend/src/service/router.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index 83a0cbd398..efe8ee46f6 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -115,10 +115,8 @@ export async function createRouter( let template: TemplateEntityV1alpha1; try { template = await entityClient.findTemplate(templateName); - } catch (e) { - // help me here - res.status(400).json({ errors: e }); - return; + } catch (err) { + throw err; } const validationResult: ValidatorResult = validate( From 55af83a78a9ce8c0591728c2fec13dbdd2d39e9a Mon Sep 17 00:00:00 2001 From: Marvin9 Date: Thu, 29 Oct 2020 14:33:09 +0530 Subject: [PATCH 08/12] chore: move entityClient to createPlugin, mock entityClient in tests --- packages/backend/src/plugins/scaffolder.ts | 6 ++ plugins/scaffolder-backend/src/index.ts | 1 + .../src/service/router.test.ts | 91 ++++++++++--------- .../scaffolder-backend/src/service/router.ts | 5 +- 4 files changed, 59 insertions(+), 44 deletions(-) diff --git a/packages/backend/src/plugins/scaffolder.ts b/packages/backend/src/plugins/scaffolder.ts index 6eacd143c1..5d36d508a5 100644 --- a/packages/backend/src/plugins/scaffolder.ts +++ b/packages/backend/src/plugins/scaffolder.ts @@ -21,7 +21,9 @@ import { Publishers, CreateReactAppTemplater, Templaters, + CatalogEntityClient, } from '@backstage/plugin-scaffolder-backend'; +import { SingleHostDiscovery } from '@backstage/backend-common'; import type { PluginEnvironment } from '../types'; import Docker from 'dockerode'; @@ -40,6 +42,9 @@ export default async function createPlugin({ const dockerClient = new Docker(); + const discovery = SingleHostDiscovery.fromConfig(config); + const entityClient = new CatalogEntityClient({ discovery }); + return await createRouter({ preparers, templaters, @@ -47,5 +52,6 @@ export default async function createPlugin({ logger, config, dockerClient, + entityClient, }); } diff --git a/plugins/scaffolder-backend/src/index.ts b/plugins/scaffolder-backend/src/index.ts index c461bfede6..28e6a2b24c 100644 --- a/plugins/scaffolder-backend/src/index.ts +++ b/plugins/scaffolder-backend/src/index.ts @@ -16,3 +16,4 @@ export * from './scaffolder'; export * from './service/router'; +export * from './lib/catalog'; diff --git a/plugins/scaffolder-backend/src/service/router.test.ts b/plugins/scaffolder-backend/src/service/router.test.ts index fae7ee8beb..c2b60a2040 100644 --- a/plugins/scaffolder-backend/src/service/router.test.ts +++ b/plugins/scaffolder-backend/src/service/router.test.ts @@ -35,6 +35,10 @@ import Docker from 'dockerode'; jest.mock('dockerode'); +const generateEntityClient: any = (template: any) => ({ + findTemplate: () => Promise.resolve(template), +}); + describe('createRouter - working directory', () => { const mockPrepare = jest.fn(); const mockPreparers = new Preparers(); @@ -74,6 +78,8 @@ describe('createRouter - working directory', () => { }, }; + const mockedEntityClient = generateEntityClient(template); + it('should throw an error when working directory does not exist or is not writable', async () => { mockAccess.mockImplementation(() => { throw new Error('access error'); @@ -87,6 +93,7 @@ describe('createRouter - working directory', () => { publishers: new Publishers(), config: ConfigReader.fromConfigs([workDirConfig('/path')]), dockerClient: new Docker(), + entityClient: mockedEntityClient, }), ).rejects.toThrow('access error'); }); @@ -99,11 +106,12 @@ describe('createRouter - working directory', () => { publishers: new Publishers(), config: ConfigReader.fromConfigs([workDirConfig('/path')]), dockerClient: new Docker(), + entityClient: mockedEntityClient, }); const app = express().use(router); await request(app).post('/v1/jobs').send({ - template, + templateName: '', values: {}, }); @@ -121,11 +129,12 @@ describe('createRouter - working directory', () => { publishers: new Publishers(), config: ConfigReader.fromConfigs([]), dockerClient: new Docker(), + entityClient: mockedEntityClient, }); const app = express().use(router); await request(app).post('/v1/jobs').send({ - template, + templateName: '', values: {}, }); @@ -137,6 +146,43 @@ describe('createRouter - working directory', () => { describe('createRouter', () => { let app: express.Express; + const template = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Template', + metadata: { + description: 'Create a new CRA website project', + name: 'create-react-app-template', + tags: ['experimental', 'react', 'cra'], + title: 'Create React App Template', + }, + spec: { + owner: 'web@example.com', + path: '.', + schema: { + properties: { + component_id: { + description: 'Unique name of the component', + title: 'Name', + type: 'string', + }, + description: { + description: 'Description of the component', + title: 'Description', + type: 'string', + }, + use_typescript: { + default: true, + description: 'Include typescript', + title: 'Use Typescript', + type: 'boolean', + }, + }, + required: ['component_id', 'use_typescript'], + }, + templater: 'cra', + type: 'website', + }, + }; beforeAll(async () => { const router = await createRouter({ @@ -146,6 +192,7 @@ describe('createRouter', () => { publishers: new Publishers(), config: ConfigReader.fromConfigs([]), dockerClient: new Docker(), + entityClient: generateEntityClient(template), }); app = express().use(router); }); @@ -155,47 +202,9 @@ describe('createRouter', () => { }); describe('POST /v1/jobs', () => { - const template = { - apiVersion: 'backstage.io/v1alpha1', - kind: 'Template', - metadata: { - description: 'Create a new CRA website project', - name: 'create-react-app-template', - tags: ['experimental', 'react', 'cra'], - title: 'Create React App Template', - }, - spec: { - owner: 'web@example.com', - path: '.', - schema: { - properties: { - component_id: { - description: 'Unique name of the component', - title: 'Name', - type: 'string', - }, - description: { - description: 'Description of the component', - title: 'Description', - type: 'string', - }, - use_typescript: { - default: true, - description: 'Include typescript', - title: 'Use Typescript', - type: 'boolean', - }, - }, - required: ['component_id', 'use_typescript'], - }, - templater: 'cra', - type: 'website', - }, - }; - it('rejects template values which do not match the template schema definition', async () => { const response = await request(app).post('/v1/jobs').send({ - template, + templateName: '', values: {}, }); diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index efe8ee46f6..e4d3d5c45a 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { SingleHostDiscovery } from '@backstage/backend-common'; import { TemplateEntityV1alpha1 } from '@backstage/catalog-model'; import { Config, JsonValue } from '@backstage/config'; import fs from 'fs-extra'; @@ -41,6 +40,7 @@ export interface RouterOptions { logger: Logger; config: Config; dockerClient: Docker; + entityClient: CatalogEntityClient; } export async function createRouter( @@ -56,13 +56,12 @@ export async function createRouter( logger: parentLogger, config, dockerClient, + entityClient, } = options; const logger = parentLogger.child({ plugin: 'scaffolder' }); const jobProcessor = new JobProcessor(); - const discovery = SingleHostDiscovery.fromConfig(config); - const entityClient = new CatalogEntityClient({ discovery }); let workingDirectory: string; if (config.has('backend.workingDirectory')) { workingDirectory = config.getString('backend.workingDirectory'); From 1ddcf191dbf5f0280383e3bb20f251016ed14889 Mon Sep 17 00:00:00 2001 From: Marvin9 Date: Thu, 29 Oct 2020 14:46:55 +0530 Subject: [PATCH 09/12] fix: use entityClient in create-app package --- .../default-app/packages/backend/src/plugins/scaffolder.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/create-app/templates/default-app/packages/backend/src/plugins/scaffolder.ts b/packages/create-app/templates/default-app/packages/backend/src/plugins/scaffolder.ts index 8de15920e9..2dc69feb45 100644 --- a/packages/create-app/templates/default-app/packages/backend/src/plugins/scaffolder.ts +++ b/packages/create-app/templates/default-app/packages/backend/src/plugins/scaffolder.ts @@ -11,7 +11,9 @@ import { CreateReactAppTemplater, Templaters, RepoVisibilityOptions, + CatalogEntityClient, } from '@backstage/plugin-scaffolder-backend'; +import { SingleHostDiscovery } from '@backstage/backend-common'; import { Octokit } from '@octokit/rest'; import { Gitlab } from '@gitbeaker/node'; import type { PluginEnvironment } from '../types'; @@ -97,6 +99,10 @@ export default async function createPlugin({ } const dockerClient = new Docker(); + + const discovery = SingleHostDiscovery.fromConfig(config); + const entityClient = new CatalogEntityClient({ discovery }); + return await createRouter({ preparers, templaters, @@ -104,5 +110,6 @@ export default async function createPlugin({ logger, config, dockerClient, + entityClient, }); } From 364939e5e3dee6511e62185a6d492a2f904e8f4a Mon Sep 17 00:00:00 2001 From: Marvin9 Date: Thu, 29 Oct 2020 14:54:30 +0530 Subject: [PATCH 10/12] chore: remove try/catch --- plugins/scaffolder-backend/src/service/router.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index e4d3d5c45a..2dc6a794fb 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import { TemplateEntityV1alpha1 } from '@backstage/catalog-model'; import { Config, JsonValue } from '@backstage/config'; import fs from 'fs-extra'; import Docker from 'dockerode'; @@ -111,12 +110,7 @@ export async function createRouter( const values: RequiredTemplateValues & Record = req.body.values; - let template: TemplateEntityV1alpha1; - try { - template = await entityClient.findTemplate(templateName); - } catch (err) { - throw err; - } + const template = await entityClient.findTemplate(templateName); const validationResult: ValidatorResult = validate( values, From 59166e5ec2b98e6389ba19c1353122c32c150a84 Mon Sep 17 00:00:00 2001 From: Marvin9 Date: Mon, 2 Nov 2020 22:19:56 +0530 Subject: [PATCH 11/12] chore: run changeset --- .changeset/weak-otters-love.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/weak-otters-love.md diff --git a/.changeset/weak-otters-love.md b/.changeset/weak-otters-love.md new file mode 100644 index 0000000000..fb4ac19d3a --- /dev/null +++ b/.changeset/weak-otters-love.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-scaffolder': minor +'@backstage/plugin-scaffolder-backend': minor +--- + +Scaffolder's API `/v1/jobs` will accept `templateName` instead of `template` Entity. From 240036496013d4cb0c52dce9d47d3548705e7a8f Mon Sep 17 00:00:00 2001 From: Marvin9 Date: Mon, 2 Nov 2020 22:48:44 +0530 Subject: [PATCH 12/12] chore: mention entityClient as an additional option of createRouter --- .changeset/weak-otters-love.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/.changeset/weak-otters-love.md b/.changeset/weak-otters-love.md index fb4ac19d3a..2c273e067b 100644 --- a/.changeset/weak-otters-love.md +++ b/.changeset/weak-otters-love.md @@ -3,4 +3,14 @@ '@backstage/plugin-scaffolder-backend': minor --- -Scaffolder's API `/v1/jobs` will accept `templateName` instead of `template` Entity. +`createRouter` of scaffolder backend will now require additional option as `entityClient` which could be generated by `CatalogEntityClient` in `plugin-scaffolder-backend` package. Here is example to generate `entityClient`. + +```js +import { CatalogEntityClient } from '@backstage/plugin-scaffolder-backend'; +import { SingleHostDiscovery } from '@backstage/backend-common'; + +const discovery = SingleHostDiscovery.fromConfig(config); +const entityClient = new CatalogEntityClient({ discovery }); +``` + +- Scaffolder's API `/v1/jobs` will accept `templateName` instead of `template` Entity.