From bd8ab057dc286eaf9b4ee89550d4c36ebd05d767 Mon Sep 17 00:00:00 2001 From: Kiss Miklos Date: Mon, 26 Sep 2022 01:35:21 +0200 Subject: [PATCH] add option to add any JsonValue for globals Signed-off-by: Kiss Miklos --- packages/backend/src/plugins/scaffolder.ts | 6 ++++ plugins/scaffolder-backend/api-report.md | 17 ++++++---- .../src/ScaffolderPlugin.ts | 4 +-- .../src/lib/templating/SecureTemplater.ts | 31 ++++++++++++++----- .../src/lib/templating/index.ts | 2 +- .../actions/builtin/createBuiltinActions.ts | 4 +-- .../actions/builtin/fetch/template.ts | 3 +- .../src/scaffolder/dryrun/createDryRunner.ts | 4 +-- .../tasks/NunjucksWorkflowRunner.ts | 3 +- .../src/scaffolder/tasks/TaskWorker.ts | 7 +++-- .../scaffolder-backend/src/service/router.ts | 4 +-- 11 files changed, 58 insertions(+), 27 deletions(-) diff --git a/packages/backend/src/plugins/scaffolder.ts b/packages/backend/src/plugins/scaffolder.ts index d079b64c28..eff781cdb7 100644 --- a/packages/backend/src/plugins/scaffolder.ts +++ b/packages/backend/src/plugins/scaffolder.ts @@ -34,5 +34,11 @@ export default async function createPlugin( reader: env.reader, identity: env.identity, scheduler: env.scheduler, + additionalTemplateGlobals: { + company: 'RoadieHQ', + now: () => { + return 'NOW !!!!'; + }, + }, }); } diff --git a/plugins/scaffolder-backend/api-report.md b/plugins/scaffolder-backend/api-report.md index 17b119e17b..9dcc45f91b 100644 --- a/plugins/scaffolder-backend/api-report.md +++ b/plugins/scaffolder-backend/api-report.md @@ -61,7 +61,7 @@ export const createBuiltinActions: ( export interface CreateBuiltInActionsOptions { additionalTemplateFilters?: Record; // (undocumented) - additionalTemplateGlobals?: Record; + additionalTemplateGlobals?: Record; catalogClient: CatalogApi; config: Config; integrations: ScmIntegrations; @@ -110,7 +110,7 @@ export function createFetchTemplateAction(options: { reader: UrlReader; integrations: ScmIntegrations; additionalTemplateFilters?: Record; - additionalTemplateGlobals?: Record; + additionalTemplateGlobals?: Record; }): TemplateAction<{ url: string; targetPath?: string | undefined; @@ -429,7 +429,7 @@ export const createPublishGitlabMergeRequestAction: (options: { branchName: string; targetPath: string; token?: string | undefined; - commitAction?: 'update' | 'create' | 'delete' | undefined; + commitAction?: 'update' | 'delete' | 'create' | undefined; projectid?: string | undefined; removeSourceBranch?: boolean | undefined; assignee?: string | undefined; @@ -451,7 +451,7 @@ export type CreateWorkerOptions = { workingDirectory: string; logger: Logger; additionalTemplateFilters?: Record; - additionalTemplateGlobals?: Record; + additionalTemplateGlobals?: Record; }; // @public @@ -542,7 +542,7 @@ export interface RouterOptions { // (undocumented) additionalTemplateFilters?: Record; // (undocumented) - additionalTemplateGlobals?: Record; + additionalTemplateGlobals?: Record; // (undocumented) catalogClient: CatalogApi; // (undocumented) @@ -599,7 +599,7 @@ export type ScaffolderPluginOptions = { taskWorkers?: number; taskBroker?: TaskBroker; additionalTemplateFilters?: Record; - additionalTemplateGlobals?: Record; + additionalTemplateGlobals?: Record; }; // @public @@ -820,4 +820,9 @@ export class TemplateActionRegistry { // @public (undocumented) export type TemplateFilter = (...args: JsonValue[]) => JsonValue | undefined; + +// @public (undocumented) +export type TemplateGlobal = + | ((...args: JsonValue[]) => JsonValue | undefined) + | JsonValue; ``` diff --git a/plugins/scaffolder-backend/src/ScaffolderPlugin.ts b/plugins/scaffolder-backend/src/ScaffolderPlugin.ts index 57d7971f50..09d7bdcbb2 100644 --- a/plugins/scaffolder-backend/src/ScaffolderPlugin.ts +++ b/plugins/scaffolder-backend/src/ScaffolderPlugin.ts @@ -26,7 +26,7 @@ import { } from '@backstage/backend-plugin-api'; import { ScmIntegrations } from '@backstage/integration'; import { catalogServiceRef } from '@backstage/plugin-catalog-node'; -import { TemplateFilter } from './lib'; +import { TemplateFilter, TemplateGlobal } from './lib'; import { createBuiltinActions, TaskBroker, TemplateAction } from './scaffolder'; import { createRouter } from './service/router'; @@ -39,7 +39,7 @@ export type ScaffolderPluginOptions = { taskWorkers?: number; taskBroker?: TaskBroker; additionalTemplateFilters?: Record; - additionalTemplateGlobals?: Record; + additionalTemplateGlobals?: Record; }; /** diff --git a/plugins/scaffolder-backend/src/lib/templating/SecureTemplater.ts b/plugins/scaffolder-backend/src/lib/templating/SecureTemplater.ts index 575eae1887..2a16ff96c1 100644 --- a/plugins/scaffolder-backend/src/lib/templating/SecureTemplater.ts +++ b/plugins/scaffolder-backend/src/lib/templating/SecureTemplater.ts @@ -65,8 +65,12 @@ const { render, renderCompat } = (() => { } if (typeof additionalTemplateGlobals !== 'undefined') { - for (const [globalName, globalFn] of Object.entries(additionalTemplateGlobals)) { - env.addGlobal(globalName, (...args) => JSON.parse(globalFn(...args))); + for (const [globalName, global] of Object.entries(additionalTemplateGlobals)) { + if (typeof global === 'function') { + env.addGlobal(globalName, (...args) => JSON.parse(global(...args))); + } else { + env.addGlobal(globalName, global); + } } } @@ -104,6 +108,11 @@ const { render, renderCompat } = (() => { /** @public */ export type TemplateFilter = (...args: JsonValue[]) => JsonValue | undefined; +/** @public */ +export type TemplateGlobal = + | ((...args: JsonValue[]) => JsonValue | undefined) + | JsonValue; + export interface SecureTemplaterOptions { /* Optional implementation of the parseRepoUrl filter */ parseRepoUrl?(repoUrl: string): RepoSpec; @@ -113,7 +122,8 @@ export interface SecureTemplaterOptions { /* Extra user-provided nunjucks filters */ additionalTemplateFilters?: Record; - additionalTemplateGlobals?: Record; + /* Extra user-provided nunjucks globals */ + additionalTemplateGlobals?: Record; } export type SecureTemplateRenderer = ( @@ -148,11 +158,16 @@ export class SecureTemplater { if (additionalTemplateGlobals) { sandbox.additionalTemplateGlobals = Object.fromEntries( Object.entries(additionalTemplateGlobals) - .filter(([_, filterFunction]) => !!filterFunction) - .map(([filterName, filterFunction]) => [ - filterName, - (...args: JsonValue[]) => JSON.stringify(filterFunction(...args)), - ]), + .filter(([_, global]) => !!global) + .map(([globalName, global]) => { + if (typeof global === 'function') { + return [ + globalName, + (...args: JsonValue[]) => JSON.stringify(global(...args)), + ]; + } + return [globalName, global]; + }), ); } const vm = new VM({ sandbox }); diff --git a/plugins/scaffolder-backend/src/lib/templating/index.ts b/plugins/scaffolder-backend/src/lib/templating/index.ts index 29d77291a1..1f9e5eb855 100644 --- a/plugins/scaffolder-backend/src/lib/templating/index.ts +++ b/plugins/scaffolder-backend/src/lib/templating/index.ts @@ -14,4 +14,4 @@ * limitations under the License. */ -export type { TemplateFilter } from './SecureTemplater'; +export type { TemplateFilter, TemplateGlobal } from './SecureTemplater'; diff --git a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts index 7581189411..e388a70f00 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/createBuiltinActions.ts @@ -28,7 +28,7 @@ import { createCatalogWriteAction, } from './catalog'; -import { TemplateFilter } from '../../../lib'; +import { TemplateFilter, TemplateGlobal } from '../../../lib'; import { TemplateAction } from '../types'; import { createDebugLogAction } from './debug'; import { createFetchPlainAction, createFetchTemplateAction } from './fetch'; @@ -82,7 +82,7 @@ export interface CreateBuiltInActionsOptions { * Template Manifests and also template skeleton files when using `fetch:template`. */ additionalTemplateFilters?: Record; - additionalTemplateGlobals?: Record; + additionalTemplateGlobals?: Record; } /** 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 47a85df9ca..d71997d496 100644 --- a/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.ts +++ b/plugins/scaffolder-backend/src/scaffolder/actions/builtin/fetch/template.ts @@ -26,6 +26,7 @@ import { isBinaryFile } from 'isbinaryfile'; import { TemplateFilter, SecureTemplater, + TemplateGlobal, } from '../../../../lib/templating/SecureTemplater'; /** @@ -39,7 +40,7 @@ export function createFetchTemplateAction(options: { reader: UrlReader; integrations: ScmIntegrations; additionalTemplateFilters?: Record; - additionalTemplateGlobals?: Record; + additionalTemplateGlobals?: Record; }) { const { reader, diff --git a/plugins/scaffolder-backend/src/scaffolder/dryrun/createDryRunner.ts b/plugins/scaffolder-backend/src/scaffolder/dryrun/createDryRunner.ts index 36a5a3728a..17f9092bff 100644 --- a/plugins/scaffolder-backend/src/scaffolder/dryrun/createDryRunner.ts +++ b/plugins/scaffolder-backend/src/scaffolder/dryrun/createDryRunner.ts @@ -25,7 +25,7 @@ import { SerializedFile, serializeDirectoryContents, } from '../../lib/files'; -import { TemplateFilter } from '../../lib/templating'; +import { TemplateFilter, TemplateGlobal } from '../../lib/templating'; import { createTemplateAction, TemplateActionRegistry } from '../actions'; import { NunjucksWorkflowRunner } from '../tasks/NunjucksWorkflowRunner'; import { TaskSecrets } from '../tasks/types'; @@ -52,7 +52,7 @@ export type TemplateTesterCreateOptions = { actionRegistry: TemplateActionRegistry; workingDirectory: string; additionalTemplateFilters?: Record; - additionalTemplateGlobals?: Record; + additionalTemplateGlobals?: Record; }; /** diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts index a9ed5bab8a..298ea16484 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/NunjucksWorkflowRunner.ts @@ -31,6 +31,7 @@ import { TemplateFilter, SecureTemplater, SecureTemplateRenderer, + TemplateGlobal, } from '../../lib/templating/SecureTemplater'; import { TaskSpec, @@ -45,7 +46,7 @@ type NunjucksWorkflowRunnerOptions = { integrations: ScmIntegrations; logger: winston.Logger; additionalTemplateFilters?: Record; - additionalTemplateGlobals?: Record; + additionalTemplateGlobals?: Record; }; type TemplateContext = { diff --git a/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts b/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts index bd0e6a6dd4..52ecd1a4dc 100644 --- a/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts +++ b/plugins/scaffolder-backend/src/scaffolder/tasks/TaskWorker.ts @@ -20,7 +20,10 @@ import { Logger } from 'winston'; import { TemplateActionRegistry } from '../actions'; import { ScmIntegrations } from '@backstage/integration'; import { assertError } from '@backstage/errors'; -import { TemplateFilter } from '../../lib/templating/SecureTemplater'; +import { + TemplateFilter, + TemplateGlobal, +} from '../../lib/templating/SecureTemplater'; /** * TaskWorkerOptions @@ -46,7 +49,7 @@ export type CreateWorkerOptions = { workingDirectory: string; logger: Logger; additionalTemplateFilters?: Record; - additionalTemplateGlobals?: Record; + additionalTemplateGlobals?: Record; }; /** diff --git a/plugins/scaffolder-backend/src/service/router.ts b/plugins/scaffolder-backend/src/service/router.ts index 592e0be79d..a36ea3c769 100644 --- a/plugins/scaffolder-backend/src/service/router.ts +++ b/plugins/scaffolder-backend/src/service/router.ts @@ -36,7 +36,7 @@ import Router from 'express-promise-router'; import { validate } from 'jsonschema'; import { Logger } from 'winston'; import { z } from 'zod'; -import { TemplateFilter } from '../lib'; +import { TemplateFilter, TemplateGlobal } from '../lib'; import { createBuiltinActions, DatabaseTaskStore, @@ -70,7 +70,7 @@ export interface RouterOptions { taskWorkers?: number; taskBroker?: TaskBroker; additionalTemplateFilters?: Record; - additionalTemplateGlobals?: Record; + additionalTemplateGlobals?: Record; identity?: IdentityApi; }