From fde4307fc407988e96d84e77843e1101d12c9b3f Mon Sep 17 00:00:00 2001 From: David Zemon Date: Fri, 21 Jan 2022 09:36:07 -0600 Subject: [PATCH] feat: [#8920] Add `nunjucksFilters` option for user-provided filters Signed-off-by: David Zemon --- .../src/lib/templating/SecureTemplater.ts | 9 ++++++++- .../actions/builtin/createBuiltinActions.ts | 12 ++++++++++-- .../src/scaffolder/actions/builtin/fetch/template.ts | 4 +++- .../src/scaffolder/tasks/NunjucksWorkflowRunner.ts | 2 ++ .../src/scaffolder/tasks/TaskWorker.ts | 3 +++ plugins/scaffolder-backend/src/service/router.ts | 4 ++++ 6 files changed, 30 insertions(+), 4 deletions(-) diff --git a/plugins/scaffolder-backend/src/lib/templating/SecureTemplater.ts b/plugins/scaffolder-backend/src/lib/templating/SecureTemplater.ts index 54c9166020..416bad3295 100644 --- a/plugins/scaffolder-backend/src/lib/templating/SecureTemplater.ts +++ b/plugins/scaffolder-backend/src/lib/templating/SecureTemplater.ts @@ -93,6 +93,9 @@ export interface SecureTemplaterOptions { /* Enables jinja compatibility and the "jsonify" filter */ cookiecutterCompat?: boolean; + + /* Extra user-provided nunjucks filters */ + additionalFilters?: Record any>; } export type SecureTemplateRenderer = ( @@ -102,7 +105,7 @@ export type SecureTemplateRenderer = ( export class SecureTemplater { static async loadRenderer(options: SecureTemplaterOptions = {}) { - const { parseRepoUrl, cookiecutterCompat } = options; + const { parseRepoUrl, cookiecutterCompat, additionalFilters } = options; let sandbox = undefined; if (parseRepoUrl) { @@ -110,6 +113,10 @@ export class SecureTemplater { parseRepoUrl: (url: string) => JSON.stringify(parseRepoUrl(url)), }; } + sandbox = { + ...sandbox, + ...additionalFilters, + }; const vm = new VM({ sandbox }); diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts index ce1e2a7f49..492e1881b8 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts @@ -53,9 +53,16 @@ export const createBuiltinActions = (options: { catalogClient: CatalogApi; containerRunner?: ContainerRunner; config: Config; + nunjucksFilters?: Record any>; }) => { - const { reader, integrations, containerRunner, catalogClient, config } = - options; + const { + reader, + integrations, + containerRunner, + catalogClient, + config, + nunjucksFilters, + } = options; const githubCredentialsProvider: GithubCredentialsProvider = DefaultGithubCredentialsProvider.fromIntegrations(integrations); @@ -67,6 +74,7 @@ export const createBuiltinActions = (options: { createFetchTemplateAction({ integrations, reader, + nunjucksFilters, }), createPublishGithubAction({ integrations, diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.ts index 2e25547e61..7d68c4a129 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.ts @@ -44,8 +44,9 @@ export type FetchTemplateInput = { export function createFetchTemplateAction(options: { reader: UrlReader; integrations: ScmIntegrations; + nunjucksFilters?: Record any>; }) { - const { reader, integrations } = options; + const { reader, integrations, nunjucksFilters } = options; return createTemplateAction({ id: 'fetch:template', @@ -182,6 +183,7 @@ export function createFetchTemplateAction(options: { const renderTemplate = await SecureTemplater.loadRenderer({ cookiecutterCompat: ctx.input.cookiecutterCompat, + additionalFilters: nunjucksFilters, }); for (const location of allEntriesInTemplate) { diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts index 46f87c1d00..1a0b9c9d16 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts @@ -44,6 +44,7 @@ type NunjucksWorkflowRunnerOptions = { actionRegistry: TemplateActionRegistry; integrations: ScmIntegrations; logger: winston.Logger; + additionalFilters?: Record any>; }; type TemplateContext = { @@ -190,6 +191,7 @@ export class NunjucksWorkflowRunner implements WorkflowRunner { parseRepoUrl(url: string) { return parseRepoUrl(url, integrations); }, + additionalFilters: this.options.additionalFilters, }); try { diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts index 8d89735361..adbcd75773 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts @@ -46,6 +46,7 @@ export type CreateWorkerOptions = { integrations: ScmIntegrations; workingDirectory: string; logger: Logger; + nunjucksFilters?: Record any>; }; /** @@ -63,6 +64,7 @@ export class TaskWorker { actionRegistry, integrations, workingDirectory, + nunjucksFilters, } = options; const legacyWorkflowRunner = new HandlebarsWorkflowRunner({ @@ -77,6 +79,7 @@ export class TaskWorker { integrations, logger, workingDirectory, + additionalFilters: nunjucksFilters, }); return new TaskWorker({ diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index f4f7398c8a..b12dace5fa 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -57,6 +57,7 @@ export interface RouterOptions { taskWorkers?: number; containerRunner?: ContainerRunner; taskBroker?: TaskBroker; + nunjucksFilters?: Record any>; } function isSupportedTemplate( @@ -83,6 +84,7 @@ export async function createRouter( actions, containerRunner, taskWorkers, + nunjucksFilters, } = options; const logger = parentLogger.child({ plugin: 'scaffolder' }); @@ -110,6 +112,7 @@ export async function createRouter( integrations, logger, workingDirectory, + nunjucksFilters, }); workers.push(worker); } @@ -122,6 +125,7 @@ export async function createRouter( containerRunner, reader, config, + nunjucksFilters, }); actionsToRegister.forEach(action => actionRegistry.register(action));