@backstage/plugin-scaffolder-backend 4.0.5 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/config.schema.json +4 -0
- package/dist/ScaffolderPlugin.cjs.js +9 -2
- package/dist/ScaffolderPlugin.cjs.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/scaffolder/actions/builtin/fetch/assertScmUserCredentials.cjs.js +34 -0
- package/dist/scaffolder/actions/builtin/fetch/assertScmUserCredentials.cjs.js.map +1 -0
- package/dist/scaffolder/actions/builtin/fetch/plain.cjs.js +9 -1
- package/dist/scaffolder/actions/builtin/fetch/plain.cjs.js.map +1 -1
- package/dist/scaffolder/actions/builtin/fetch/plainFile.cjs.js +9 -1
- package/dist/scaffolder/actions/builtin/fetch/plainFile.cjs.js.map +1 -1
- package/dist/scaffolder/actions/builtin/fetch/template.cjs.js +8 -0
- package/dist/scaffolder/actions/builtin/fetch/template.cjs.js.map +1 -1
- package/dist/scaffolder/actions/builtin/fetch/templateFile.cjs.js +8 -0
- package/dist/scaffolder/actions/builtin/fetch/templateFile.cjs.js.map +1 -1
- package/dist/scaffolder/tasks/DatabaseTaskStore.cjs.js +17 -18
- package/dist/scaffolder/tasks/DatabaseTaskStore.cjs.js.map +1 -1
- package/dist/scaffolder/tasks/NunjucksWorkflowRunner.cjs.js +127 -44
- package/dist/scaffolder/tasks/NunjucksWorkflowRunner.cjs.js.map +1 -1
- package/dist/scaffolder/tasks/logger.cjs.js +101 -7
- package/dist/scaffolder/tasks/logger.cjs.js.map +1 -1
- package/dist/schema/openapi/generated/router.cjs.js +6 -6
- package/dist/schema/openapi/generated/router.cjs.js.map +1 -1
- package/dist/service/router.cjs.js +20 -4
- package/dist/service/router.cjs.js.map +1 -1
- package/dist/service/rules.cjs.js +12 -0
- package/dist/service/rules.cjs.js.map +1 -1
- package/dist/util/checkPermissions.cjs.js +3 -0
- package/dist/util/checkPermissions.cjs.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NunjucksWorkflowRunner.cjs.js","sources":["../../../src/scaffolder/tasks/NunjucksWorkflowRunner.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { InputError, NotAllowedError, stringifyError } from '@backstage/errors';\nimport { ScmIntegrations } from '@backstage/integration';\nimport {\n TaskRecovery,\n TaskSpec,\n TaskSpecV1beta3,\n TaskStep,\n} from '@backstage/plugin-scaffolder-common';\nimport { JsonArray, JsonObject, JsonValue } from '@backstage/types';\nimport fs from 'fs-extra';\nimport { validate as validateJsonSchema } from 'jsonschema';\nimport path from 'node:path';\nimport {\n createTemplateRenderer,\n PreparedTemplateContext,\n TemplateCapabilities,\n TemplateContext as NunjitsuTemplateContext,\n TemplateRenderer,\n TemplateValue as NunjitsuTemplateValue,\n} from 'nunjitsu';\nimport * as winston from 'winston';\nimport { TemplateActionRegistry } from '../actions/TemplateActionRegistry';\nimport {\n filterConditionalItems,\n generateExampleOutput,\n isTruthy,\n} from './helper';\nimport { TaskTrackType, WorkflowResponse, WorkflowRunner } from './types';\n\nimport type {\n AuditorService,\n LoggerService,\n PermissionsService,\n} from '@backstage/backend-plugin-api';\nimport type { MetricsService } from '@backstage/backend-plugin-api/alpha';\nimport { UserEntity } from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\nimport {\n AuthorizeResult,\n PolicyDecision,\n} from '@backstage/plugin-permission-common';\nimport { createConditionAuthorizer } from '@backstage/plugin-permission-node';\nimport { actionExecutePermission } from '@backstage/plugin-scaffolder-common/alpha';\nimport {\n TaskContext,\n TaskSecrets,\n TemplateAction,\n} from '@backstage/plugin-scaffolder-node';\nimport {\n CheckpointContext,\n CheckpointState,\n} from '@backstage/plugin-scaffolder-node/alpha';\nimport { resolveDefaultEnvironment } from '../../lib/defaultEnvironment';\nimport { createDefaultFilters } from '../../lib/templating/filters/createDefaultFilters';\nimport { scaffolderActionRules } from '../../service/rules';\nimport { createCounterMetric, createHistogramMetric } from '../../util/metrics';\nimport {\n collectTemplateCapabilities,\n convertFiltersToRecord,\n} from '../../util/templating';\nimport { BackstageLoggerTransport, WinstonLogger } from './logger';\n\ntype NunjucksWorkflowRunnerOptions = {\n workingDirectory: string;\n actionRegistry: TemplateActionRegistry;\n integrations: ScmIntegrations;\n logger: LoggerService;\n auditor?: AuditorService;\n templateCapabilities?: TemplateCapabilities;\n permissions?: PermissionsService;\n config?: Config;\n metrics: MetricsService;\n};\n\ntype TemplateContext = {\n parameters: JsonObject;\n environment: JsonObject;\n EXPERIMENTAL_recovery?: TaskRecovery;\n steps: {\n [stepName: string]: { output: { [outputName: string]: JsonValue } };\n };\n secrets?: Record<string, string>;\n user?: {\n entity?: UserEntity;\n ref?: string;\n };\n each?: JsonValue;\n context: {\n task: {\n id: string;\n };\n };\n};\n\nconst isValidTaskSpec = (taskSpec: TaskSpec): taskSpec is TaskSpecV1beta3 => {\n return taskSpec.apiVersion === 'scaffolder.backstage.io/v1beta3';\n};\n\nfunction stringifyEachLogValue(value: unknown): string {\n if (Array.isArray(value)) {\n return value\n .map(item =>\n item === null || item === undefined ? '' : stringifyEachLogValue(item),\n )\n .join(',');\n }\n if (value !== null && typeof value === 'object') {\n return '[object Object]';\n }\n return String(value);\n}\n\nconst createStepLogger = ({\n task,\n step,\n rootLogger,\n redactions,\n}: {\n task: TaskContext;\n step: TaskStep;\n rootLogger: LoggerService;\n redactions?: Record<string, string>;\n}) => {\n const taskLogger = WinstonLogger.create({\n level: process.env.LOG_LEVEL || 'info',\n format: winston.format.combine(\n winston.format.colorize(),\n winston.format.simple(),\n ),\n transports: [new BackstageLoggerTransport(rootLogger, task, step.id)],\n });\n\n taskLogger.addRedactions(Object.values(redactions ?? {}));\n\n return { taskLogger };\n};\n\n/**\n * Recursively compares two rendered objects and returns string values from\n * `withSecrets` that differ from their counterpart in `withoutSecrets`.\n * These are values that were influenced by secret interpolation and should\n * be added as log redactions.\n */\nfunction collectSecretRedactions(\n withSecrets: unknown,\n withoutSecrets: unknown,\n): string[] {\n if (typeof withSecrets === 'string') {\n return withSecrets !== withoutSecrets ? [withSecrets] : [];\n }\n if (Array.isArray(withSecrets)) {\n const other = Array.isArray(withoutSecrets) ? withoutSecrets : [];\n return withSecrets.flatMap((val, i) =>\n collectSecretRedactions(val, other[i]),\n );\n }\n if (withSecrets && typeof withSecrets === 'object') {\n const other =\n withoutSecrets && typeof withoutSecrets === 'object'\n ? (withoutSecrets as Record<string, unknown>)\n : {};\n return Object.entries(withSecrets as Record<string, unknown>).flatMap(\n ([key, val]) => collectSecretRedactions(val, other[key]),\n );\n }\n return [];\n}\n\n/**\n * Extracts all string values from a nested object structure.\n * Used as a fallback when the comparison render fails.\n */\nfunction extractStringValues(obj: unknown): string[] {\n if (typeof obj === 'string') return [obj];\n if (Array.isArray(obj)) return obj.flatMap(extractStringValues);\n if (obj && typeof obj === 'object') {\n return Object.entries(obj).flatMap(([key, val]) => [\n key,\n ...extractStringValues(val),\n ]);\n }\n return [];\n}\n\nconst isActionAuthorized = createConditionAuthorizer(\n Object.values(scaffolderActionRules),\n);\n\nexport class NunjucksWorkflowRunner implements WorkflowRunner {\n private readonly defaultTemplateCapabilities: TemplateCapabilities;\n private readonly options: NunjucksWorkflowRunnerOptions;\n private environment: {\n parameters: JsonObject;\n secrets?: Record<string, string>;\n } = { parameters: {}, secrets: {} };\n\n private readonly tracker: ReturnType<typeof scaffoldingTracker>;\n\n constructor(options: NunjucksWorkflowRunnerOptions) {\n this.options = options;\n this.defaultTemplateCapabilities = collectTemplateCapabilities({\n filters: convertFiltersToRecord(\n createDefaultFilters({\n integrations: this.options.integrations,\n }),\n ),\n });\n this.tracker = scaffoldingTracker(options.metrics);\n }\n\n async getEnvironmentConfig(): Promise<{\n parameters: JsonObject;\n secrets?: TaskSecrets;\n }> {\n if (this.options.config) {\n const defaultEnvironment = resolveDefaultEnvironment(this.options.config);\n return {\n parameters: defaultEnvironment.parameters,\n secrets: defaultEnvironment.secrets,\n };\n }\n\n return {\n parameters: {},\n secrets: {},\n };\n }\n\n private render<T>(\n input: T,\n context: PreparedTemplateContext,\n templateRenderer: TemplateRenderer,\n ): T {\n return JSON.parse(JSON.stringify(input), (_key, value) => {\n try {\n if (typeof value === 'string') {\n return templateRenderer.renderValue(value, context);\n }\n } catch {\n return value;\n }\n return value;\n });\n }\n\n async executeStep(\n task: TaskContext,\n step: TaskStep,\n context: TemplateContext,\n preparedContext: PreparedTemplateContext,\n templateRenderer: TemplateRenderer,\n taskTrack: TaskTrackType,\n workspacePath: string,\n decision: PolicyDecision,\n ) {\n const stepTrack = await this.tracker.stepStart(task, step);\n\n if (task.cancelSignal.aborted) {\n throw new Error(\n `Step ${step.id} (${step.name}) of task ${task.taskId} has been cancelled.`,\n );\n }\n\n try {\n if (\n step.if === false ||\n (typeof step.if === 'string' &&\n step.each === undefined &&\n !isTruthy(this.render(step.if, preparedContext, templateRenderer)))\n ) {\n await stepTrack.skipFalsy();\n return preparedContext;\n }\n const action: TemplateAction<JsonObject> =\n await this.options.actionRegistry.get(step.action, {\n credentials: await task.getInitiatorCredentials(),\n });\n const { taskLogger } = createStepLogger({\n task,\n step,\n rootLogger: this.options.logger,\n redactions: {\n ...task.secrets,\n ...this.environment?.secrets,\n },\n });\n\n if (task.isDryRun) {\n const redactedSecrets = Object.fromEntries(\n Object.entries(task.secrets ?? {}).map(secret => [secret[0], '***']),\n );\n\n const redactedEnvironmentSecrets = Object.fromEntries(\n Object.entries(this.environment?.secrets ?? {}).map(secret => [\n secret[0],\n '***',\n ]),\n );\n const dryRunContext = preparedContext\n .withValue(['environment'], {\n parameters: this.environment?.parameters || {},\n secrets: redactedEnvironmentSecrets,\n } as NunjitsuTemplateValue)\n .withValue(['secrets'], redactedSecrets);\n const debugInput =\n (step.input &&\n this.render(step.input, dryRunContext, templateRenderer)) ??\n {};\n taskLogger.info(\n `Running ${\n action.id\n } in dry-run mode with inputs (secrets redacted): ${JSON.stringify(\n debugInput,\n undefined,\n 2,\n )}`,\n );\n if (!action.supportsDryRun) {\n await taskTrack.skipDryRun(step, action);\n const outputSchema = action.schema?.output;\n if (outputSchema) {\n context.steps[step.id] = {\n output: generateExampleOutput(outputSchema) as {\n [name in string]: JsonValue;\n },\n };\n } else {\n context.steps[step.id] = { output: {} };\n }\n return preparedContext.withValue(\n ['steps', step.id],\n context.steps[step.id] as unknown as NunjitsuTemplateValue,\n );\n }\n }\n\n const preIterationContext = {\n ...context,\n environment: {\n parameters: this.environment?.parameters ?? {},\n secrets: task.isDryRun ? {} : this.environment?.secrets ?? {},\n },\n secrets: task.secrets ?? {},\n };\n const preparedPreIterationContext = preparedContext\n .withValue(\n ['environment'],\n preIterationContext.environment as NunjitsuTemplateValue,\n )\n .withValue(\n ['secrets'],\n preIterationContext.secrets as NunjitsuTemplateValue,\n );\n\n const resolvedEach =\n step.each &&\n this.render(step.each, preparedPreIterationContext, templateRenderer);\n\n if (step.each && !resolvedEach) {\n throw new InputError(\n `Invalid value on action ${action.id}.each parameter, \"${step.each}\" cannot be resolved to a value`,\n );\n }\n\n const iterations = (\n resolvedEach\n ? Object.entries(resolvedEach).map(([key, value]) => ({\n each: { key, value },\n }))\n : [{}]\n ).map(i => {\n const preparedFullContext =\n 'each' in i\n ? preparedPreIterationContext.withValue(\n ['each'],\n i.each as NunjitsuTemplateValue,\n )\n : preparedPreIterationContext;\n // Evaluate if condition once per iteration, only when using 'each'\n const shouldRun =\n !('each' in i) ||\n !step.if ||\n isTruthy(this.render(step.if, preparedFullContext, templateRenderer));\n\n return {\n ...i,\n preparedContext: preparedFullContext,\n shouldRun,\n // Secrets are only passed when templating the input to actions for security reasons\n input: step.input\n ? this.render(step.input, preparedFullContext, templateRenderer)\n : {},\n };\n });\n for (const iteration of iterations) {\n if (!iteration.shouldRun) {\n // No need to check schema or authorization for iterations that will not run\n continue;\n }\n\n const actionId = `${action.id}${\n iteration.each ? `[${iteration.each.key}]` : ''\n }`;\n\n if (action.schema?.input) {\n const validateResult = validateJsonSchema(\n iteration.input,\n action.schema.input,\n );\n if (!validateResult.valid) {\n const errors = validateResult.errors.join(', ');\n throw new InputError(\n `Invalid input passed to action ${actionId}, ${errors}`,\n );\n }\n }\n if (\n !isActionAuthorized(decision, {\n action: action.id,\n input: iteration.input,\n })\n ) {\n throw new NotAllowedError(\n `Unauthorized action: ${actionId}. The action is not allowed. Input: ${JSON.stringify(\n iteration.input,\n null,\n 2,\n )}`,\n );\n }\n }\n const tmpDirs = new Array<string>();\n const stepOutput: { [outputName: string]: JsonValue } = {};\n const prevTaskState = await task.getTaskState?.();\n\n for (const iteration of iterations) {\n if (iteration.each) {\n if (!iteration.shouldRun) {\n taskLogger.info(\n `Skipping step each: ${JSON.stringify(\n iteration.each,\n (key, value) => (key ? stringifyEachLogValue(value) : value),\n 0,\n )}`,\n );\n continue;\n }\n taskLogger.info(\n `Running step each: ${JSON.stringify(\n iteration.each,\n (key, value) => (key ? stringifyEachLogValue(value) : value),\n 0,\n )}`,\n );\n }\n\n // Redact any rendered values that were influenced by secrets.\n // Re-render the input without secrets and diff against the real render\n // to find values that changed due to secret interpolation.\n if (step.input) {\n const hasSecrets =\n Object.keys(task.secrets ?? {}).length > 0 ||\n Object.keys(this.environment?.secrets ?? {}).length > 0;\n\n if (hasSecrets) {\n try {\n const preparedContextNoSecrets = iteration.preparedContext\n .withValue(['secrets'], {})\n .withValue(['environment', 'secrets'], {});\n const inputWithoutSecrets = this.render(\n step.input,\n preparedContextNoSecrets,\n templateRenderer,\n );\n taskLogger.addRedactions(\n collectSecretRedactions(iteration.input, inputWithoutSecrets),\n );\n } catch {\n taskLogger.addRedactions(extractStringValues(iteration.input));\n }\n }\n }\n\n await action.handler({\n input: iteration.input,\n task: {\n id: await task.getWorkspaceName(),\n },\n secrets: task.secrets ?? {},\n logger: taskLogger,\n workspacePath,\n async checkpoint<T extends JsonValue | void>(\n opts: CheckpointContext<T>,\n ) {\n const { key: checkpointKey, fn } = opts;\n const key = `v1.task.checkpoint.${step.id}.${checkpointKey}`;\n\n try {\n let prevValue: T | undefined;\n let value: T;\n\n try {\n if (prevTaskState) {\n const prevState = (\n prevTaskState.state?.checkpoints as CheckpointState\n )?.[key];\n\n if (prevState && prevState.status === 'success') {\n prevValue = prevState.value as T;\n }\n }\n\n value = prevValue !== undefined ? prevValue : await fn();\n } catch (err) {\n try {\n await task.updateCheckpoint?.({\n key,\n status: 'failed',\n reason: stringifyError(err),\n });\n } catch (persistenceError) {\n throw new AggregateError(\n [err, persistenceError],\n `Checkpoint '${checkpointKey}' failed and its failure state could not be persisted`,\n );\n }\n throw err;\n }\n\n if (prevValue === undefined) {\n await task.updateCheckpoint?.({\n key,\n status: 'success',\n value: value ?? {},\n });\n }\n return value;\n } finally {\n await task.serializeWorkspace?.({ path: workspacePath });\n }\n },\n createTemporaryDirectory: async () => {\n const tmpDir = await fs.mkdtemp(\n `${workspacePath}_step-${step.id}-`,\n );\n tmpDirs.push(tmpDir);\n return tmpDir;\n },\n output(name: string, value: JsonValue) {\n if (step.each) {\n stepOutput[name] = stepOutput[name] || [];\n (stepOutput[name] as JsonArray).push(value);\n } else {\n stepOutput[name] = value;\n }\n },\n templateInfo: task.spec.templateInfo,\n user: task.spec.user,\n isDryRun: task.isDryRun,\n signal: task.cancelSignal,\n getInitiatorCredentials: () => task.getInitiatorCredentials(),\n step: {\n id: step.id,\n name: step.name,\n },\n });\n }\n\n // Remove all temporary directories that were created when executing the action\n for (const tmpDir of tmpDirs) {\n await fs.remove(tmpDir);\n }\n\n context.steps[step.id] = { output: stepOutput };\n const updatedPreparedContext = preparedContext.withValue(\n ['steps', step.id],\n context.steps[step.id] as unknown as NunjitsuTemplateValue,\n );\n\n if (task.cancelSignal.aborted) {\n throw new Error(\n `Step ${step.id} (${step.name}) of task ${task.taskId} has been cancelled.`,\n );\n }\n\n await stepTrack.markSuccessful();\n return updatedPreparedContext;\n } catch (err) {\n await taskTrack.markFailed(step, err);\n await stepTrack.markFailed();\n throw err;\n } finally {\n await task.serializeWorkspace?.({ path: workspacePath });\n }\n }\n\n async execute(task: TaskContext): Promise<WorkflowResponse> {\n if (!isValidTaskSpec(task.spec)) {\n throw new InputError(\n 'Wrong template version executed with the workflow engine',\n );\n }\n const taskId = await task.getWorkspaceName();\n\n const workspacePath = path.join(this.options.workingDirectory, taskId);\n\n const { templateCapabilities } = this.options;\n\n this.environment = await this.getEnvironmentConfig();\n\n // Track whether any step has failed, used by status check functions\n const taskState = { failed: false };\n\n // Track whether a status check global (always/failure) was invoked during rendering\n const statusCheckInvoked = { value: false };\n\n const templateRenderer = createTemplateRenderer({\n allowRegexExecution: true,\n filters: {\n ...this.defaultTemplateCapabilities.filters,\n ...templateCapabilities?.filters,\n },\n globals: {\n ...templateCapabilities?.globals,\n always: () => {\n statusCheckInvoked.value = true;\n return true;\n },\n failure: () => {\n statusCheckInvoked.value = true;\n return taskState.failed;\n },\n },\n });\n try {\n await task.rehydrateWorkspace?.({ taskId, targetPath: workspacePath });\n\n const taskTrack = await this.tracker.taskStart(task);\n await fs.ensureDir(workspacePath);\n\n const context: TemplateContext = {\n parameters: task.spec.parameters,\n environment: {\n parameters: this.environment?.parameters || {},\n secrets: {},\n },\n steps: {},\n user: task.spec.user,\n context: {\n task: {\n id: taskId,\n },\n },\n };\n let preparedContext = templateRenderer.prepareContext(\n context as unknown as NunjitsuTemplateContext,\n );\n\n const [decision]: PolicyDecision[] =\n this.options.permissions && task.spec.steps.length\n ? await this.options.permissions.authorizeConditional(\n [{ permission: actionExecutePermission }],\n { credentials: await task.getInitiatorCredentials() },\n )\n : [{ result: AuthorizeResult.ALLOW }];\n\n let firstError: Error | undefined;\n const allErrors: Array<{ step: TaskStep; error: Error }> = [];\n\n for (const step of task.spec.steps) {\n // If a previous step failed, only run steps whose `if` condition\n // invokes a status check global (${{ always() }} or ${{ failure() }})\n if (taskState.failed) {\n if (typeof step.if !== 'string') {\n await task.emitLog(\n `Skipping step ${step.id} because a previous step failed`,\n { stepId: step.id, status: 'skipped' },\n );\n continue;\n }\n\n // Render the if condition to detect status check function usage\n statusCheckInvoked.value = false;\n this.render(step.if, preparedContext, templateRenderer);\n\n if (!statusCheckInvoked.value) {\n await task.emitLog(\n `Skipping step ${step.id} because a previous step failed`,\n { stepId: step.id, status: 'skipped' },\n );\n continue;\n }\n }\n\n try {\n preparedContext = await this.executeStep(\n task,\n step,\n context,\n preparedContext,\n templateRenderer,\n taskTrack,\n workspacePath,\n decision,\n );\n } catch (err) {\n const error = err as Error;\n allErrors.push({ step, error });\n\n if (!firstError) {\n firstError = error;\n } else {\n // Log subsequent errors to preserve debugging information\n this.options.logger.error(\n `Additional error in step ${step.id} (${step.name}): ${error.message}`,\n error,\n );\n await task.emitLog(\n `Additional error occurred: ${error.message}\\n${error.stack}`,\n { stepId: step.id, status: 'failed' },\n );\n }\n taskState.failed = true;\n }\n }\n\n if (firstError) {\n // If there were multiple errors, add context to the first error\n if (allErrors.length > 1) {\n const additionalErrorSummary = allErrors\n .slice(1)\n .map(({ step }) => `${step.id} (${step.name})`)\n .join(', ');\n this.options.logger.warn(\n `Task failed with ${allErrors.length} errors. First error from step ${allErrors[0].step.id}. Additional failures in: ${additionalErrorSummary}`,\n );\n }\n throw firstError;\n }\n\n const output = this.render(\n task.spec.output,\n preparedContext,\n templateRenderer,\n );\n\n // Filter output links and text items based on their `if` condition\n if (Array.isArray(output?.links)) {\n output.links = filterConditionalItems(output.links);\n }\n if (Array.isArray(output?.text)) {\n output.text = filterConditionalItems(output.text);\n }\n\n await taskTrack.markSuccessful();\n await task.cleanWorkspace?.();\n\n return { output };\n } finally {\n if (workspacePath) {\n await fs.remove(workspacePath);\n }\n }\n }\n}\n\nfunction scaffoldingTracker(metrics: MetricsService) {\n // prom-client metrics are deprecated in favour of OpenTelemetry metrics.\n const promTaskCount = createCounterMetric({\n name: 'scaffolder_task_count',\n help: 'Count of task runs',\n labelNames: ['template', 'user', 'result'],\n });\n const promTaskDuration = createHistogramMetric({\n name: 'scaffolder_task_duration',\n help: 'Duration of a task run',\n labelNames: ['template', 'result'],\n });\n const promStepCount = createCounterMetric({\n name: 'scaffolder_step_count',\n help: 'Count of step runs',\n labelNames: ['template', 'step', 'result'],\n });\n const promStepDuration = createHistogramMetric({\n name: 'scaffolder_step_duration',\n help: 'Duration of a step runs',\n labelNames: ['template', 'step', 'result'],\n });\n\n const taskCount = metrics.createCounter('scaffolder.task.count', {\n description: 'Total number of scaffolder tasks executed',\n });\n\n const taskDuration = metrics.createHistogram('scaffolder.task.duration', {\n description: 'Time taken to complete a scaffolder task end-to-end',\n unit: 's',\n });\n\n const stepCount = metrics.createCounter('scaffolder.step.count', {\n description: 'Total number of individual scaffolder action steps executed',\n });\n\n const stepDuration = metrics.createHistogram('scaffolder.step.duration', {\n description: 'Time taken to complete a single scaffolder action step',\n unit: 's',\n });\n\n async function taskStart(task: TaskContext) {\n await task.emitLog(`Starting up task with ${task.spec.steps.length} steps`);\n const template = task.spec.templateInfo?.entityRef || '';\n const user = task.spec.user?.ref || '';\n\n const startTime = process.hrtime();\n const taskTimer = promTaskDuration.startTimer({\n template,\n });\n\n function endTime() {\n const delta = process.hrtime(startTime);\n return delta[0] + delta[1] / 1e9;\n }\n\n async function skipDryRun(\n step: TaskStep,\n action: TemplateAction<JsonObject>,\n ) {\n task.emitLog(`Skipping because ${action.id} does not support dry-run`, {\n stepId: step.id,\n status: 'skipped',\n });\n }\n\n async function markSuccessful() {\n promTaskCount.inc({\n template,\n user,\n result: 'ok',\n });\n taskTimer({ result: 'ok' });\n\n taskCount.add(1, { template, user, result: 'ok' });\n taskDuration.record(endTime(), {\n template,\n result: 'ok',\n });\n }\n\n async function markFailed(step: TaskStep, err: Error) {\n await task.emitLog(String(err.stack), {\n stepId: step.id,\n status: 'failed',\n });\n promTaskCount.inc({\n template,\n user,\n result: 'failed',\n });\n taskTimer({ result: 'failed' });\n\n taskCount.add(1, { template, user, result: 'failed' });\n taskDuration.record(endTime(), {\n template,\n result: 'failed',\n });\n }\n\n async function markCancelled(step: TaskStep) {\n await task.emitLog(`Step ${step.id} has been cancelled.`, {\n stepId: step.id,\n status: 'cancelled',\n });\n promTaskCount.inc({\n template,\n user,\n result: 'cancelled',\n });\n taskTimer({ result: 'cancelled' });\n\n taskCount.add(1, { template, user, result: 'cancelled' });\n taskDuration.record(endTime(), {\n template,\n result: 'cancelled',\n });\n }\n\n return {\n skipDryRun,\n markCancelled,\n markSuccessful,\n markFailed,\n };\n }\n\n async function stepStart(task: TaskContext, step: TaskStep) {\n await task.emitLog(`Beginning step ${step.name}`, {\n stepId: step.id,\n status: 'processing',\n });\n const template = task.spec.templateInfo?.entityRef || '';\n\n const startTime = process.hrtime();\n const stepTimer = promStepDuration.startTimer({\n template,\n step: step.name,\n });\n\n function endTime() {\n const delta = process.hrtime(startTime);\n return delta[0] + delta[1] / 1e9;\n }\n\n async function markSuccessful() {\n await task.emitLog(`Finished step ${step.name}`, {\n stepId: step.id,\n status: 'completed',\n });\n promStepCount.inc({\n template,\n step: step.name,\n result: 'ok',\n });\n stepTimer({ result: 'ok' });\n\n stepCount.add(1, { template, step: step.name, result: 'ok' });\n stepDuration.record(endTime(), {\n template,\n step: step.name,\n result: 'ok',\n });\n }\n\n async function markCancelled() {\n promStepCount.inc({\n template,\n step: step.name,\n result: 'cancelled',\n });\n stepTimer({ result: 'cancelled' });\n\n stepCount.add(1, { template, step: step.name, result: 'cancelled' });\n stepDuration.record(endTime(), {\n template,\n step: step.name,\n result: 'cancelled',\n });\n }\n\n async function markFailed() {\n promStepCount.inc({\n template,\n step: step.name,\n result: 'failed',\n });\n stepTimer({ result: 'failed' });\n\n stepCount.add(1, { template, step: step.name, result: 'failed' });\n stepDuration.record(endTime(), {\n template,\n step: step.name,\n result: 'failed',\n });\n }\n\n async function skipFalsy() {\n await task.emitLog(\n `Skipping step ${step.id} because its if condition was false`,\n { stepId: step.id, status: 'skipped' },\n );\n stepTimer({ result: 'skipped' });\n\n stepCount.add(1, { template, step: step.name, result: 'skipped' });\n stepDuration.record(endTime(), {\n template,\n step: step.name,\n result: 'skipped',\n });\n }\n\n return {\n markCancelled,\n markFailed,\n markSuccessful,\n skipFalsy,\n };\n }\n\n return {\n taskStart,\n stepStart,\n };\n}\n"],"names":["WinstonLogger","winston","BackstageLoggerTransport","createConditionAuthorizer","scaffolderActionRules","collectTemplateCapabilities","convertFiltersToRecord","createDefaultFilters","defaultEnvironment","resolveDefaultEnvironment","isTruthy","generateExampleOutput","InputError","validateJsonSchema","errors","NotAllowedError","stringifyError","fs","path","createTemplateRenderer","actionExecutePermission","AuthorizeResult","filterConditionalItems","metrics","createCounterMetric","createHistogramMetric"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"NunjucksWorkflowRunner.cjs.js","sources":["../../../src/scaffolder/tasks/NunjucksWorkflowRunner.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { InputError, NotAllowedError, stringifyError } from '@backstage/errors';\nimport { ScmIntegrations } from '@backstage/integration';\nimport {\n TaskRecovery,\n TaskSpec,\n TaskSpecV1beta3,\n TaskStep,\n} from '@backstage/plugin-scaffolder-common';\nimport { JsonArray, JsonObject, JsonValue } from '@backstage/types';\nimport fs from 'fs-extra';\nimport { validate as validateJsonSchema } from 'jsonschema';\nimport { toPath } from 'lodash';\nimport path from 'node:path';\nimport {\n createTemplateRenderer,\n PreparedTemplateContext,\n TemplateCapabilities,\n TemplateContext as NunjitsuTemplateContext,\n TemplateRenderer,\n TemplateValue as NunjitsuTemplateValue,\n} from 'nunjitsu';\nimport * as winston from 'winston';\nimport { z } from 'zod/v3';\nimport { TemplateActionRegistry } from '../actions/TemplateActionRegistry';\nimport {\n filterConditionalItems,\n generateExampleOutput,\n isTruthy,\n} from './helper';\nimport { TaskTrackType, WorkflowResponse, WorkflowRunner } from './types';\n\nimport type {\n AuditorService,\n LoggerService,\n PermissionsService,\n} from '@backstage/backend-plugin-api';\nimport type { MetricsService } from '@backstage/backend-plugin-api/alpha';\nimport { UserEntity } from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\nimport {\n AuthorizeResult,\n type PermissionCondition,\n type PermissionCriteria,\n PolicyDecision,\n} from '@backstage/plugin-permission-common';\nimport {\n createConditionAuthorizer,\n isAndCriteria,\n isNotCriteria,\n isOrCriteria,\n} from '@backstage/plugin-permission-node';\nimport { actionExecutePermission } from '@backstage/plugin-scaffolder-common/alpha';\nimport {\n TaskContext,\n TaskSecrets,\n TemplateAction,\n} from '@backstage/plugin-scaffolder-node';\nimport {\n CheckpointContext,\n CheckpointState,\n} from '@backstage/plugin-scaffolder-node/alpha';\nimport { resolveDefaultEnvironment } from '../../lib/defaultEnvironment';\nimport { createDefaultFilters } from '../../lib/templating/filters/createDefaultFilters';\nimport { scaffolderActionRules } from '../../service/rules';\nimport { createCounterMetric, createHistogramMetric } from '../../util/metrics';\nimport {\n collectTemplateCapabilities,\n convertFiltersToRecord,\n} from '../../util/templating';\nimport { BackstageLoggerTransport, WinstonLogger } from './logger';\n\ntype NunjucksWorkflowRunnerOptions = {\n workingDirectory: string;\n actionRegistry: TemplateActionRegistry;\n integrations: ScmIntegrations;\n logger: LoggerService;\n auditor?: AuditorService;\n templateCapabilities?: TemplateCapabilities;\n permissions?: PermissionsService;\n config?: Config;\n metrics: MetricsService;\n};\n\ntype TemplateContext = {\n parameters: JsonObject;\n environment: JsonObject;\n EXPERIMENTAL_recovery?: TaskRecovery;\n steps: {\n [stepName: string]: { output: { [outputName: string]: JsonValue } };\n };\n secrets?: Record<string, string>;\n user?: {\n entity?: UserEntity;\n ref?: string;\n };\n each?: JsonValue;\n context: {\n task: {\n id: string;\n };\n };\n};\n\nconst isValidTaskSpec = (taskSpec: TaskSpec): taskSpec is TaskSpecV1beta3 => {\n return taskSpec.apiVersion === 'scaffolder.backstage.io/v1beta3';\n};\n\nfunction stringifyEachLogValue(value: unknown): string {\n if (Array.isArray(value)) {\n return value\n .map(item =>\n item === null || item === undefined ? '' : stringifyEachLogValue(item),\n )\n .join(',');\n }\n if (value !== null && typeof value === 'object') {\n return '[object Object]';\n }\n return String(value);\n}\n\nconst createStepLogger = ({\n task,\n step,\n rootLogger,\n redactions,\n}: {\n task: TaskContext;\n step: TaskStep;\n rootLogger: LoggerService;\n redactions?: Iterable<string>;\n}) => {\n const taskLogger = WinstonLogger.create({\n level: process.env.LOG_LEVEL || 'info',\n format: winston.format.combine(\n winston.format.colorize(),\n winston.format.simple(),\n ),\n transports: [new BackstageLoggerTransport(rootLogger, task, step.id)],\n });\n\n taskLogger.addRedactions(redactions ?? []);\n\n return { taskLogger };\n};\n\n/**\n * Recursively compares two rendered objects and returns string keys and values\n * from `withSecrets` that differ from their counterpart in `withoutSecrets`.\n * These were influenced by secret interpolation and should be added as log\n * redactions.\n */\nfunction collectSecretRedactions(\n withSecrets: unknown,\n withoutSecrets: unknown,\n): string[] {\n if (typeof withSecrets === 'string') {\n return withSecrets !== withoutSecrets ? [withSecrets] : [];\n }\n if (Array.isArray(withSecrets)) {\n const other = Array.isArray(withoutSecrets) ? withoutSecrets : [];\n return withSecrets.flatMap((val, i) =>\n collectSecretRedactions(val, other[i]),\n );\n }\n if (withSecrets && typeof withSecrets === 'object') {\n const otherEntries =\n withoutSecrets && typeof withoutSecrets === 'object'\n ? Object.entries(withoutSecrets as Record<string, unknown>)\n : [];\n return Object.entries(withSecrets as Record<string, unknown>).flatMap(\n ([key, value], index) => {\n const otherEntry = otherEntries[index];\n if (!otherEntry) {\n return [key, ...extractStringValues(value)];\n }\n const [otherKey, otherValue] = otherEntry;\n return [\n ...(key !== otherKey ? [key] : []),\n ...collectSecretRedactions(value, otherValue),\n ];\n },\n );\n }\n return [];\n}\n\n/**\n * Extracts all string values from a nested object structure.\n * Used as a fallback when the comparison render fails.\n */\nfunction extractStringValues(obj: unknown): string[] {\n if (typeof obj === 'string') return [obj];\n if (Array.isArray(obj)) return obj.flatMap(extractStringValues);\n if (obj && typeof obj === 'object') {\n return Object.entries(obj).flatMap(([key, val]) => [\n key,\n ...extractStringValues(val),\n ]);\n }\n return [];\n}\n\nconst isActionAuthorized = createConditionAuthorizer(\n Object.values(scaffolderActionRules),\n);\n\nconst stringPathConditionSchema = z.object({\n rule: z.literal('HAS_STRING_PROPERTY'),\n params: z.object({\n key: z.string().refine(key => toPath(key).join('.') === 'path'),\n value: z.string(),\n }),\n});\n\nconst numericGroupPathSchema = z.number().or(z.string().regex(/^\\d+$/u));\n\nfunction getStringPathConditions(\n criteria: PermissionCriteria<PermissionCondition>,\n): Array<string> {\n switch (true) {\n case isAndCriteria(criteria):\n return criteria.allOf.flatMap(getStringPathConditions);\n case isOrCriteria(criteria):\n return criteria.anyOf.flatMap(getStringPathConditions);\n case isNotCriteria(criteria):\n return getStringPathConditions(criteria.not);\n default: {\n const condition = stringPathConditionSchema.safeParse(criteria);\n return condition.success ? [condition.data.params.value] : [];\n }\n }\n}\n\nfunction isActionInputAuthorized(\n decision: PolicyDecision,\n action: string,\n input: JsonObject,\n): boolean {\n if (!isActionAuthorized(decision, { action, input })) {\n return false;\n }\n\n if (\n decision.result !== AuthorizeResult.CONDITIONAL ||\n !action.split(':').includes('group') ||\n !numericGroupPathSchema.safeParse(input.path).success\n ) {\n return true;\n }\n\n return getStringPathConditions(decision.conditions).every(candidatePath =>\n isActionAuthorized(decision, {\n action,\n input: { ...input, path: candidatePath },\n }),\n );\n}\n\nexport class NunjucksWorkflowRunner implements WorkflowRunner {\n private readonly defaultTemplateCapabilities: TemplateCapabilities;\n private readonly options: NunjucksWorkflowRunnerOptions;\n private environment: {\n parameters: JsonObject;\n secrets?: Record<string, string>;\n } = { parameters: {}, secrets: {} };\n\n private readonly tracker: ReturnType<typeof scaffoldingTracker>;\n\n constructor(options: NunjucksWorkflowRunnerOptions) {\n this.options = options;\n this.defaultTemplateCapabilities = collectTemplateCapabilities({\n filters: convertFiltersToRecord(\n createDefaultFilters({\n integrations: this.options.integrations,\n }),\n ),\n });\n this.tracker = scaffoldingTracker(options.metrics);\n }\n\n async getEnvironmentConfig(): Promise<{\n parameters: JsonObject;\n secrets?: TaskSecrets;\n }> {\n if (this.options.config) {\n const defaultEnvironment = resolveDefaultEnvironment(this.options.config);\n return {\n parameters: defaultEnvironment.parameters,\n secrets: defaultEnvironment.secrets,\n };\n }\n\n return {\n parameters: {},\n secrets: {},\n };\n }\n\n private render<T>(\n input: T,\n context: PreparedTemplateContext,\n templateRenderer: TemplateRenderer,\n ): T {\n return JSON.parse(JSON.stringify(input), (_key, value) => {\n try {\n if (typeof value === 'string') {\n return templateRenderer.renderValue(value, context);\n }\n } catch {\n return value;\n }\n return value;\n });\n }\n\n async executeStep(\n task: TaskContext,\n step: TaskStep,\n context: TemplateContext,\n preparedContext: PreparedTemplateContext,\n templateRenderer: TemplateRenderer,\n taskTrack: TaskTrackType,\n workspacePath: string,\n decision: PolicyDecision,\n ) {\n const stepTrack = await this.tracker.stepStart(task, step);\n const { taskLogger } = createStepLogger({\n task,\n step,\n rootLogger: this.options.logger,\n redactions: [\n ...Object.values(task.secrets ?? {}),\n ...Object.values(this.environment?.secrets ?? {}),\n ],\n });\n\n if (task.cancelSignal.aborted) {\n throw new Error(\n `Step ${step.id} (${step.name}) of task ${task.taskId} has been cancelled.`,\n );\n }\n\n try {\n if (\n step.if === false ||\n (typeof step.if === 'string' &&\n step.each === undefined &&\n !isTruthy(this.render(step.if, preparedContext, templateRenderer)))\n ) {\n await stepTrack.skipFalsy();\n return preparedContext;\n }\n const action: TemplateAction<JsonObject> =\n await this.options.actionRegistry.get(step.action, {\n credentials: await task.getInitiatorCredentials(),\n });\n\n if (task.isDryRun) {\n const redactedSecrets = Object.fromEntries(\n Object.entries(task.secrets ?? {}).map(secret => [secret[0], '***']),\n );\n\n const redactedEnvironmentSecrets = Object.fromEntries(\n Object.entries(this.environment?.secrets ?? {}).map(secret => [\n secret[0],\n '***',\n ]),\n );\n const dryRunContext = preparedContext\n .withValue(['environment'], {\n parameters: this.environment?.parameters || {},\n secrets: redactedEnvironmentSecrets,\n } as NunjitsuTemplateValue)\n .withValue(['secrets'], redactedSecrets);\n const debugInput =\n (step.input &&\n this.render(step.input, dryRunContext, templateRenderer)) ??\n {};\n taskLogger.info(\n `Running ${\n action.id\n } in dry-run mode with inputs (secrets redacted): ${JSON.stringify(\n debugInput,\n undefined,\n 2,\n )}`,\n );\n if (!action.supportsDryRun) {\n await taskTrack.skipDryRun(step, action);\n const outputSchema = action.schema?.output;\n if (outputSchema) {\n context.steps[step.id] = {\n output: generateExampleOutput(outputSchema) as {\n [name in string]: JsonValue;\n },\n };\n } else {\n context.steps[step.id] = { output: {} };\n }\n return preparedContext.withValue(\n ['steps', step.id],\n context.steps[step.id] as unknown as NunjitsuTemplateValue,\n );\n }\n }\n\n const preIterationContext = {\n ...context,\n environment: {\n parameters: this.environment?.parameters ?? {},\n secrets: task.isDryRun ? {} : this.environment?.secrets ?? {},\n },\n secrets: task.secrets ?? {},\n };\n const preparedPreIterationContext = preparedContext\n .withValue(\n ['environment'],\n preIterationContext.environment as NunjitsuTemplateValue,\n )\n .withValue(\n ['secrets'],\n preIterationContext.secrets as NunjitsuTemplateValue,\n );\n const hasSecrets =\n Object.keys(task.secrets ?? {}).length > 0 ||\n Object.keys(this.environment?.secrets ?? {}).length > 0;\n const preparedPreIterationContextNoSecrets = preparedPreIterationContext\n .withValue(['secrets'], {})\n .withValue(['environment', 'secrets'], {});\n\n const resolvedEach =\n step.each &&\n this.render(step.each, preparedPreIterationContext, templateRenderer);\n\n if (step.each && !resolvedEach) {\n throw new InputError(\n `Invalid value on action ${action.id}.each parameter, \"${step.each}\" cannot be resolved to a value`,\n );\n }\n\n // Discover secret-derived iteration values before logging or executing\n // any iteration. The iteration value is already resolved by the time it\n // is added to each iteration's context, so input-only comparison cannot\n // identify it as secret-derived.\n let eachWithoutSecretsEntries: [string, unknown][] | undefined;\n if (step.each && resolvedEach && hasSecrets) {\n try {\n const eachWithoutSecrets = this.render(\n step.each,\n preparedPreIterationContextNoSecrets,\n templateRenderer,\n );\n eachWithoutSecretsEntries =\n Array.isArray(resolvedEach) && Array.isArray(eachWithoutSecrets)\n ? Object.keys(resolvedEach).map(\n key =>\n [key, eachWithoutSecrets[Number(key)]] as [string, unknown],\n )\n : Object.entries(eachWithoutSecrets);\n taskLogger.addRedactions(\n collectSecretRedactions(\n Object.entries(resolvedEach),\n eachWithoutSecretsEntries,\n ),\n );\n } catch {\n taskLogger.addRedactions(extractStringValues(resolvedEach));\n }\n }\n\n const iterations = (\n resolvedEach\n ? Object.entries(resolvedEach).map(([key, value], index) => {\n const eachWithoutSecrets = eachWithoutSecretsEntries?.[index];\n return {\n each: { key, value },\n eachWithoutSecrets: eachWithoutSecrets\n ? {\n key: eachWithoutSecrets[0],\n value: eachWithoutSecrets[1],\n }\n : {},\n };\n })\n : [{}]\n ).map(i => {\n const preparedFullContext =\n 'each' in i\n ? preparedPreIterationContext.withValue(\n ['each'],\n i.each as NunjitsuTemplateValue,\n )\n : preparedPreIterationContext;\n const preparedContextNoSecrets =\n 'each' in i\n ? preparedPreIterationContextNoSecrets.withValue(\n ['each'],\n i.eachWithoutSecrets as NunjitsuTemplateValue,\n )\n : preparedPreIterationContextNoSecrets;\n // Evaluate if condition once per iteration, only when using 'each'\n const shouldRun =\n !('each' in i) ||\n !step.if ||\n isTruthy(this.render(step.if, preparedFullContext, templateRenderer));\n\n return {\n ...i,\n preparedContext: preparedFullContext,\n preparedContextNoSecrets,\n shouldRun,\n // Secrets are only passed when templating the input to actions for security reasons\n input: step.input\n ? this.render(step.input, preparedFullContext, templateRenderer)\n : {},\n };\n });\n for (const iteration of iterations) {\n if (hasSecrets && iteration.each) {\n taskLogger.addRedactions(\n collectSecretRedactions(\n iteration.each,\n iteration.eachWithoutSecrets,\n ),\n );\n }\n if (!iteration.shouldRun) {\n // No need to check schema or authorization for iterations that will not run\n continue;\n }\n\n // Redact any rendered values that were influenced by secrets.\n // Re-render the input without secrets and diff against the real render\n // to find values that changed due to secret interpolation.\n if (step.input) {\n if (hasSecrets) {\n try {\n const inputWithoutSecrets = this.render(\n step.input,\n iteration.preparedContextNoSecrets,\n templateRenderer,\n );\n taskLogger.addRedactions(\n collectSecretRedactions(iteration.input, inputWithoutSecrets),\n );\n } catch {\n taskLogger.addRedactions(extractStringValues(iteration.input));\n }\n }\n }\n\n const actionId = `${action.id}${\n iteration.each ? `[${iteration.each.key}]` : ''\n }`;\n\n if (action.schema?.input) {\n const validateResult = validateJsonSchema(\n iteration.input,\n action.schema.input,\n );\n if (!validateResult.valid) {\n const errors = validateResult.errors.join(', ');\n throw new InputError(\n `Invalid input passed to action ${actionId}, ${errors}`,\n );\n }\n }\n if (!isActionInputAuthorized(decision, action.id, iteration.input)) {\n throw new NotAllowedError(\n `Unauthorized action: ${action.id}. The action is not allowed.`,\n );\n }\n }\n const tmpDirs = new Array<string>();\n const stepOutput: { [outputName: string]: JsonValue } = {};\n const prevTaskState = await task.getTaskState?.();\n\n for (const iteration of iterations) {\n if (iteration.each) {\n if (!iteration.shouldRun) {\n taskLogger.info(\n `Skipping step each: ${JSON.stringify(\n iteration.each,\n (key, value) => (key ? stringifyEachLogValue(value) : value),\n 0,\n )}`,\n );\n continue;\n }\n taskLogger.info(\n `Running step each: ${JSON.stringify(\n iteration.each,\n (key, value) => (key ? stringifyEachLogValue(value) : value),\n 0,\n )}`,\n );\n }\n\n await action.handler({\n input: iteration.input,\n task: {\n id: await task.getWorkspaceName(),\n },\n secrets: task.secrets ?? {},\n logger: taskLogger,\n workspacePath,\n async checkpoint<T extends JsonValue | void>(\n opts: CheckpointContext<T>,\n ) {\n const { key: checkpointKey, fn } = opts;\n const key = `v1.task.checkpoint.${step.id}.${checkpointKey}`;\n\n try {\n let prevValue: T | undefined;\n let value: T;\n\n try {\n if (prevTaskState) {\n const prevState = (\n prevTaskState.state?.checkpoints as CheckpointState\n )?.[key];\n\n if (prevState && prevState.status === 'success') {\n prevValue = prevState.value as T;\n }\n }\n\n value = prevValue !== undefined ? prevValue : await fn();\n } catch (err) {\n try {\n await task.updateCheckpoint?.({\n key,\n status: 'failed',\n reason: stringifyError(taskLogger.redactError(err)),\n });\n } catch (persistenceError) {\n throw new AggregateError(\n [err, persistenceError],\n `Checkpoint '${checkpointKey}' failed and its failure state could not be persisted`,\n );\n }\n throw err;\n }\n\n if (prevValue === undefined) {\n await task.updateCheckpoint?.({\n key,\n status: 'success',\n value: value ?? {},\n });\n }\n return value;\n } finally {\n await task.serializeWorkspace?.({ path: workspacePath });\n }\n },\n createTemporaryDirectory: async () => {\n const tmpDir = await fs.mkdtemp(\n `${workspacePath}_step-${step.id}-`,\n );\n tmpDirs.push(tmpDir);\n return tmpDir;\n },\n output(name: string, value: JsonValue) {\n if (step.each) {\n stepOutput[name] = stepOutput[name] || [];\n (stepOutput[name] as JsonArray).push(value);\n } else {\n stepOutput[name] = value;\n }\n },\n templateInfo: task.spec.templateInfo,\n user: task.spec.user,\n isDryRun: task.isDryRun,\n signal: task.cancelSignal,\n getInitiatorCredentials: () => task.getInitiatorCredentials(),\n step: {\n id: step.id,\n name: step.name,\n },\n });\n }\n\n // Remove all temporary directories that were created when executing the action\n for (const tmpDir of tmpDirs) {\n await fs.remove(tmpDir);\n }\n\n context.steps[step.id] = { output: stepOutput };\n const updatedPreparedContext = preparedContext.withValue(\n ['steps', step.id],\n context.steps[step.id] as unknown as NunjitsuTemplateValue,\n );\n\n if (task.cancelSignal.aborted) {\n throw new Error(\n `Step ${step.id} (${step.name}) of task ${task.taskId} has been cancelled.`,\n );\n }\n\n await stepTrack.markSuccessful();\n return updatedPreparedContext;\n } catch (cause) {\n const err = taskLogger.redactError(cause);\n await taskTrack.markFailed(step, err);\n await stepTrack.markFailed();\n throw err;\n } finally {\n await task.serializeWorkspace?.({ path: workspacePath });\n }\n }\n\n async execute(task: TaskContext): Promise<WorkflowResponse> {\n if (!isValidTaskSpec(task.spec)) {\n throw new InputError(\n 'Wrong template version executed with the workflow engine',\n );\n }\n const taskId = await task.getWorkspaceName();\n\n const workspacePath = path.join(this.options.workingDirectory, taskId);\n\n const { templateCapabilities } = this.options;\n\n this.environment = await this.getEnvironmentConfig();\n\n // Track whether any step has failed, used by status check functions\n const taskState = { failed: false };\n\n // Track whether a status check global (always/failure) was invoked during rendering\n const statusCheckInvoked = { value: false };\n\n const templateRenderer = createTemplateRenderer({\n allowRegexExecution: true,\n filters: {\n ...this.defaultTemplateCapabilities.filters,\n ...templateCapabilities?.filters,\n },\n globals: {\n ...templateCapabilities?.globals,\n always: () => {\n statusCheckInvoked.value = true;\n return true;\n },\n failure: () => {\n statusCheckInvoked.value = true;\n return taskState.failed;\n },\n },\n });\n try {\n await task.rehydrateWorkspace?.({ taskId, targetPath: workspacePath });\n\n const taskTrack = await this.tracker.taskStart(task);\n await fs.ensureDir(workspacePath);\n\n const context: TemplateContext = {\n parameters: task.spec.parameters,\n environment: {\n parameters: this.environment?.parameters || {},\n secrets: {},\n },\n steps: {},\n user: task.spec.user,\n context: {\n task: {\n id: taskId,\n },\n },\n };\n let preparedContext = templateRenderer.prepareContext(\n context as unknown as NunjitsuTemplateContext,\n );\n\n const [decision]: PolicyDecision[] =\n this.options.permissions && task.spec.steps.length\n ? await this.options.permissions.authorizeConditional(\n [{ permission: actionExecutePermission }],\n { credentials: await task.getInitiatorCredentials() },\n )\n : [{ result: AuthorizeResult.ALLOW }];\n\n let firstError: Error | undefined;\n const allErrors: Array<{ step: TaskStep; error: Error }> = [];\n\n for (const step of task.spec.steps) {\n // If a previous step failed, only run steps whose `if` condition\n // invokes a status check global (${{ always() }} or ${{ failure() }})\n if (taskState.failed) {\n if (typeof step.if !== 'string') {\n await task.emitLog(\n `Skipping step ${step.id} because a previous step failed`,\n { stepId: step.id, status: 'skipped' },\n );\n continue;\n }\n\n // Render the if condition to detect status check function usage\n statusCheckInvoked.value = false;\n this.render(step.if, preparedContext, templateRenderer);\n\n if (!statusCheckInvoked.value) {\n await task.emitLog(\n `Skipping step ${step.id} because a previous step failed`,\n { stepId: step.id, status: 'skipped' },\n );\n continue;\n }\n }\n\n try {\n preparedContext = await this.executeStep(\n task,\n step,\n context,\n preparedContext,\n templateRenderer,\n taskTrack,\n workspacePath,\n decision,\n );\n } catch (err) {\n const error = err as Error;\n allErrors.push({ step, error });\n\n if (!firstError) {\n firstError = error;\n } else {\n // Log subsequent errors to preserve debugging information\n this.options.logger.error(\n `Additional error in step ${step.id} (${step.name}): ${error.message}`,\n error,\n );\n await task.emitLog(\n `Additional error occurred: ${error.message}\\n${error.stack}`,\n { stepId: step.id, status: 'failed' },\n );\n }\n taskState.failed = true;\n }\n }\n\n if (firstError) {\n // If there were multiple errors, add context to the first error\n if (allErrors.length > 1) {\n const additionalErrorSummary = allErrors\n .slice(1)\n .map(({ step }) => `${step.id} (${step.name})`)\n .join(', ');\n this.options.logger.warn(\n `Task failed with ${allErrors.length} errors. First error from step ${allErrors[0].step.id}. Additional failures in: ${additionalErrorSummary}`,\n );\n }\n throw firstError;\n }\n\n const output = this.render(\n task.spec.output,\n preparedContext,\n templateRenderer,\n );\n\n // Filter output links and text items based on their `if` condition\n if (Array.isArray(output?.links)) {\n output.links = filterConditionalItems(output.links);\n }\n if (Array.isArray(output?.text)) {\n output.text = filterConditionalItems(output.text);\n }\n\n await taskTrack.markSuccessful();\n await task.cleanWorkspace?.();\n\n return { output };\n } finally {\n if (workspacePath) {\n await fs.remove(workspacePath);\n }\n }\n }\n}\n\nfunction scaffoldingTracker(metrics: MetricsService) {\n // prom-client metrics are deprecated in favour of OpenTelemetry metrics.\n const promTaskCount = createCounterMetric({\n name: 'scaffolder_task_count',\n help: 'Count of task runs',\n labelNames: ['template', 'user', 'result'],\n });\n const promTaskDuration = createHistogramMetric({\n name: 'scaffolder_task_duration',\n help: 'Duration of a task run',\n labelNames: ['template', 'result'],\n });\n const promStepCount = createCounterMetric({\n name: 'scaffolder_step_count',\n help: 'Count of step runs',\n labelNames: ['template', 'step', 'result'],\n });\n const promStepDuration = createHistogramMetric({\n name: 'scaffolder_step_duration',\n help: 'Duration of a step runs',\n labelNames: ['template', 'step', 'result'],\n });\n\n const taskCount = metrics.createCounter('scaffolder.task.count', {\n description: 'Total number of scaffolder tasks executed',\n });\n\n const taskDuration = metrics.createHistogram('scaffolder.task.duration', {\n description: 'Time taken to complete a scaffolder task end-to-end',\n unit: 's',\n });\n\n const stepCount = metrics.createCounter('scaffolder.step.count', {\n description: 'Total number of individual scaffolder action steps executed',\n });\n\n const stepDuration = metrics.createHistogram('scaffolder.step.duration', {\n description: 'Time taken to complete a single scaffolder action step',\n unit: 's',\n });\n\n async function taskStart(task: TaskContext) {\n await task.emitLog(`Starting up task with ${task.spec.steps.length} steps`);\n const template = task.spec.templateInfo?.entityRef || '';\n const user = task.spec.user?.ref || '';\n\n const startTime = process.hrtime();\n const taskTimer = promTaskDuration.startTimer({\n template,\n });\n\n function endTime() {\n const delta = process.hrtime(startTime);\n return delta[0] + delta[1] / 1e9;\n }\n\n async function skipDryRun(\n step: TaskStep,\n action: TemplateAction<JsonObject>,\n ) {\n task.emitLog(`Skipping because ${action.id} does not support dry-run`, {\n stepId: step.id,\n status: 'skipped',\n });\n }\n\n async function markSuccessful() {\n promTaskCount.inc({\n template,\n user,\n result: 'ok',\n });\n taskTimer({ result: 'ok' });\n\n taskCount.add(1, { template, user, result: 'ok' });\n taskDuration.record(endTime(), {\n template,\n result: 'ok',\n });\n }\n\n async function markFailed(step: TaskStep, err: Error) {\n await task.emitLog(String(err.stack), {\n stepId: step.id,\n status: 'failed',\n });\n promTaskCount.inc({\n template,\n user,\n result: 'failed',\n });\n taskTimer({ result: 'failed' });\n\n taskCount.add(1, { template, user, result: 'failed' });\n taskDuration.record(endTime(), {\n template,\n result: 'failed',\n });\n }\n\n async function markCancelled(step: TaskStep) {\n await task.emitLog(`Step ${step.id} has been cancelled.`, {\n stepId: step.id,\n status: 'cancelled',\n });\n promTaskCount.inc({\n template,\n user,\n result: 'cancelled',\n });\n taskTimer({ result: 'cancelled' });\n\n taskCount.add(1, { template, user, result: 'cancelled' });\n taskDuration.record(endTime(), {\n template,\n result: 'cancelled',\n });\n }\n\n return {\n skipDryRun,\n markCancelled,\n markSuccessful,\n markFailed,\n };\n }\n\n async function stepStart(task: TaskContext, step: TaskStep) {\n await task.emitLog(`Beginning step ${step.name}`, {\n stepId: step.id,\n status: 'processing',\n });\n const template = task.spec.templateInfo?.entityRef || '';\n\n const startTime = process.hrtime();\n const stepTimer = promStepDuration.startTimer({\n template,\n step: step.name,\n });\n\n function endTime() {\n const delta = process.hrtime(startTime);\n return delta[0] + delta[1] / 1e9;\n }\n\n async function markSuccessful() {\n await task.emitLog(`Finished step ${step.name}`, {\n stepId: step.id,\n status: 'completed',\n });\n promStepCount.inc({\n template,\n step: step.name,\n result: 'ok',\n });\n stepTimer({ result: 'ok' });\n\n stepCount.add(1, { template, step: step.name, result: 'ok' });\n stepDuration.record(endTime(), {\n template,\n step: step.name,\n result: 'ok',\n });\n }\n\n async function markCancelled() {\n promStepCount.inc({\n template,\n step: step.name,\n result: 'cancelled',\n });\n stepTimer({ result: 'cancelled' });\n\n stepCount.add(1, { template, step: step.name, result: 'cancelled' });\n stepDuration.record(endTime(), {\n template,\n step: step.name,\n result: 'cancelled',\n });\n }\n\n async function markFailed() {\n promStepCount.inc({\n template,\n step: step.name,\n result: 'failed',\n });\n stepTimer({ result: 'failed' });\n\n stepCount.add(1, { template, step: step.name, result: 'failed' });\n stepDuration.record(endTime(), {\n template,\n step: step.name,\n result: 'failed',\n });\n }\n\n async function skipFalsy() {\n await task.emitLog(\n `Skipping step ${step.id} because its if condition was false`,\n { stepId: step.id, status: 'skipped' },\n );\n stepTimer({ result: 'skipped' });\n\n stepCount.add(1, { template, step: step.name, result: 'skipped' });\n stepDuration.record(endTime(), {\n template,\n step: step.name,\n result: 'skipped',\n });\n }\n\n return {\n markCancelled,\n markFailed,\n markSuccessful,\n skipFalsy,\n };\n }\n\n return {\n taskStart,\n stepStart,\n };\n}\n"],"names":["WinstonLogger","winston","BackstageLoggerTransport","createConditionAuthorizer","scaffolderActionRules","z","toPath","isAndCriteria","isOrCriteria","isNotCriteria","AuthorizeResult","collectTemplateCapabilities","convertFiltersToRecord","createDefaultFilters","defaultEnvironment","resolveDefaultEnvironment","isTruthy","generateExampleOutput","InputError","validateJsonSchema","errors","NotAllowedError","stringifyError","fs","path","createTemplateRenderer","actionExecutePermission","filterConditionalItems","metrics","createCounterMetric","createHistogramMetric"],"mappings":"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"}
|
|
@@ -52,6 +52,8 @@ class BackstageLoggerTransport extends Transport__default.default {
|
|
|
52
52
|
class WinstonLogger {
|
|
53
53
|
#winston;
|
|
54
54
|
#addRedactions;
|
|
55
|
+
#redact;
|
|
56
|
+
#redactError;
|
|
55
57
|
/**
|
|
56
58
|
* Creates a {@link WinstonLogger} instance.
|
|
57
59
|
*/
|
|
@@ -65,7 +67,12 @@ class WinstonLogger {
|
|
|
65
67
|
if (options.meta) {
|
|
66
68
|
logger = logger.child(options.meta);
|
|
67
69
|
}
|
|
68
|
-
return new WinstonLogger(
|
|
70
|
+
return new WinstonLogger(
|
|
71
|
+
logger,
|
|
72
|
+
redacter.add,
|
|
73
|
+
redacter.redact,
|
|
74
|
+
redacter.redactError
|
|
75
|
+
);
|
|
69
76
|
}
|
|
70
77
|
/**
|
|
71
78
|
* Creates a winston log formatter for redacting secrets.
|
|
@@ -73,13 +80,85 @@ class WinstonLogger {
|
|
|
73
80
|
static redacter() {
|
|
74
81
|
const redactionSet = /* @__PURE__ */ new Set();
|
|
75
82
|
let redactionPattern = void 0;
|
|
83
|
+
const redact = (value) => {
|
|
84
|
+
if (!redactionPattern) {
|
|
85
|
+
return value;
|
|
86
|
+
}
|
|
87
|
+
const ranges = Array.from(value.matchAll(redactionPattern), (match) => ({
|
|
88
|
+
start: match.index,
|
|
89
|
+
end: match.index + match[1].length
|
|
90
|
+
}));
|
|
91
|
+
if (ranges.length === 0) {
|
|
92
|
+
return value;
|
|
93
|
+
}
|
|
94
|
+
const mergedRanges = [];
|
|
95
|
+
for (const range of ranges) {
|
|
96
|
+
const previous = mergedRanges.at(-1);
|
|
97
|
+
if (previous && range.start < previous.end) {
|
|
98
|
+
previous.end = Math.max(previous.end, range.end);
|
|
99
|
+
} else {
|
|
100
|
+
mergedRanges.push(range);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
let result = "";
|
|
104
|
+
let cursor = 0;
|
|
105
|
+
for (const range of mergedRanges) {
|
|
106
|
+
result += `${value.slice(cursor, range.start)}***`;
|
|
107
|
+
cursor = range.end;
|
|
108
|
+
}
|
|
109
|
+
return result + value.slice(cursor);
|
|
110
|
+
};
|
|
111
|
+
const createSanitizedError = (name = "Error", message = "Task failed", stack) => {
|
|
112
|
+
const sanitizedError = new Error(message);
|
|
113
|
+
sanitizedError.name = name;
|
|
114
|
+
if (stack !== void 0) {
|
|
115
|
+
sanitizedError.stack = stack;
|
|
116
|
+
}
|
|
117
|
+
return sanitizedError;
|
|
118
|
+
};
|
|
119
|
+
const createUnknownError = (value) => {
|
|
120
|
+
try {
|
|
121
|
+
return createSanitizedError(
|
|
122
|
+
"Error",
|
|
123
|
+
redact(`unknown error '${String(value)}'`)
|
|
124
|
+
);
|
|
125
|
+
} catch {
|
|
126
|
+
return createSanitizedError(
|
|
127
|
+
"Error",
|
|
128
|
+
`unknown error of type '${typeof value}'`
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
const redactError = (error) => {
|
|
133
|
+
if ((typeof error !== "object" || error === null) && typeof error !== "function") {
|
|
134
|
+
return typeof error === "string" ? createSanitizedError("Error", redact(error)) : createUnknownError(error);
|
|
135
|
+
}
|
|
136
|
+
const errorLike = error;
|
|
137
|
+
let originalName;
|
|
138
|
+
let originalMessage;
|
|
139
|
+
let originalStack;
|
|
140
|
+
try {
|
|
141
|
+
originalName = errorLike.name;
|
|
142
|
+
originalMessage = errorLike.message;
|
|
143
|
+
originalStack = errorLike.stack;
|
|
144
|
+
} catch {
|
|
145
|
+
return createSanitizedError();
|
|
146
|
+
}
|
|
147
|
+
if (typeof originalName !== "string" || !originalName || typeof originalMessage !== "string") {
|
|
148
|
+
return createUnknownError(error);
|
|
149
|
+
}
|
|
150
|
+
const name = redact(originalName);
|
|
151
|
+
const message = redact(originalMessage);
|
|
152
|
+
const stack = typeof originalStack === "string" ? redact(originalStack) : void 0;
|
|
153
|
+
return createSanitizedError(name, message, stack);
|
|
154
|
+
};
|
|
76
155
|
return {
|
|
77
156
|
format: winston.format((obj) => {
|
|
78
157
|
if (!redactionPattern || !obj) {
|
|
79
158
|
return obj;
|
|
80
159
|
}
|
|
81
160
|
if (typeof obj[tripleBeam.MESSAGE] === "string") {
|
|
82
|
-
obj[tripleBeam.MESSAGE] = obj[tripleBeam.MESSAGE]
|
|
161
|
+
obj[tripleBeam.MESSAGE] = redact(obj[tripleBeam.MESSAGE]);
|
|
83
162
|
}
|
|
84
163
|
return obj;
|
|
85
164
|
})(),
|
|
@@ -99,10 +178,12 @@ class WinstonLogger {
|
|
|
99
178
|
}
|
|
100
179
|
}
|
|
101
180
|
if (added > 0) {
|
|
102
|
-
const redactions = Array.from(redactionSet).map((r) => escapeRegExp(r)).join("|");
|
|
103
|
-
redactionPattern = new RegExp(`(${redactions})`, "g");
|
|
181
|
+
const redactions = Array.from(redactionSet).sort((a, b) => b.length - a.length).map((r) => escapeRegExp(r)).join("|");
|
|
182
|
+
redactionPattern = new RegExp(`(?=(${redactions}))`, "g");
|
|
104
183
|
}
|
|
105
|
-
}
|
|
184
|
+
},
|
|
185
|
+
redact,
|
|
186
|
+
redactError
|
|
106
187
|
};
|
|
107
188
|
}
|
|
108
189
|
/**
|
|
@@ -138,9 +219,11 @@ class WinstonLogger {
|
|
|
138
219
|
})
|
|
139
220
|
);
|
|
140
221
|
}
|
|
141
|
-
constructor(winston, addRedactions) {
|
|
222
|
+
constructor(winston, addRedactions, redact, redactError) {
|
|
142
223
|
this.#winston = winston;
|
|
143
224
|
this.#addRedactions = addRedactions;
|
|
225
|
+
this.#redact = redact;
|
|
226
|
+
this.#redactError = redactError;
|
|
144
227
|
}
|
|
145
228
|
error(message, meta) {
|
|
146
229
|
this.#winston.error(message, meta);
|
|
@@ -155,11 +238,22 @@ class WinstonLogger {
|
|
|
155
238
|
this.#winston.debug(message, meta);
|
|
156
239
|
}
|
|
157
240
|
child(meta) {
|
|
158
|
-
return new WinstonLogger(
|
|
241
|
+
return new WinstonLogger(
|
|
242
|
+
this.#winston.child(meta),
|
|
243
|
+
this.#addRedactions,
|
|
244
|
+
this.#redact,
|
|
245
|
+
this.#redactError
|
|
246
|
+
);
|
|
159
247
|
}
|
|
160
248
|
addRedactions(redactions) {
|
|
161
249
|
this.#addRedactions?.(redactions);
|
|
162
250
|
}
|
|
251
|
+
redact(value) {
|
|
252
|
+
return this.#redact?.(value) ?? value;
|
|
253
|
+
}
|
|
254
|
+
redactError(error) {
|
|
255
|
+
return this.#redactError?.(error) ?? new Error("Task failed");
|
|
256
|
+
}
|
|
163
257
|
}
|
|
164
258
|
|
|
165
259
|
exports.BackstageLoggerTransport = BackstageLoggerTransport;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.cjs.js","sources":["../../../src/scaffolder/tasks/logger.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n LoggerService,\n RootLoggerService,\n} from '@backstage/backend-plugin-api';\nimport { JsonObject } from '@backstage/types';\nimport { Format, TransformableInfo } from 'logform';\nimport Transport, { TransportStreamOptions } from 'winston-transport';\nimport { Logger, format, createLogger, transports } from 'winston';\nimport { LEVEL, MESSAGE, SPLAT } from 'triple-beam';\nimport { TaskContext } from '@backstage/plugin-scaffolder-node';\nimport _ from 'lodash';\n\n/**\n * Escapes a given string to be used inside a RegExp.\n *\n * Taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions\n */\nconst escapeRegExp = (text: string) => {\n return text.replace(/[.*+?^${}(\\)|[\\]\\\\]/g, '\\\\$&');\n};\n\ninterface WinstonLoggerOptions {\n meta?: JsonObject;\n level: string;\n format: Format;\n transports: Transport[];\n}\n\n// This is a workaround for being able to preserve the log format of the root logger.\n// Will revisit all of this implementation once we can break the router to use only `LoggerService`.\nexport class BackstageLoggerTransport extends Transport {\n private readonly backstageLogger: LoggerService;\n private readonly taskContext: TaskContext;\n private readonly stepId: string;\n\n constructor(\n backstageLogger: LoggerService,\n taskContext: TaskContext,\n stepId: string,\n opts?: TransportStreamOptions,\n ) {\n super(opts);\n this.backstageLogger = backstageLogger;\n this.taskContext = taskContext;\n this.stepId = stepId;\n }\n\n log(info: TransformableInfo, callback: VoidFunction) {\n if (typeof info !== 'object' || info === null) {\n callback();\n return;\n }\n\n const message = info[MESSAGE];\n const level = info[LEVEL];\n\n switch (level) {\n case 'error':\n this.backstageLogger.error(String(message));\n break;\n case 'warn':\n this.backstageLogger.warn(String(message));\n break;\n case 'info':\n this.backstageLogger.info(String(message));\n break;\n case 'debug':\n this.backstageLogger.debug(String(message));\n break;\n default:\n this.backstageLogger.info(String(message));\n break;\n }\n\n this.taskContext.emitLog(String(message), { stepId: this.stepId });\n callback();\n }\n}\n\nexport class WinstonLogger implements RootLoggerService {\n #winston: Logger;\n #addRedactions?: (redactions: Iterable<string>) => void;\n\n /**\n * Creates a {@link WinstonLogger} instance.\n */\n static create(options: WinstonLoggerOptions): WinstonLogger {\n const redacter = WinstonLogger.redacter();\n\n let logger = createLogger({\n level: options.level,\n format: format.combine(options.format, redacter.format),\n transports: options.transports ?? new transports.Console(),\n });\n\n if (options.meta) {\n logger = logger.child(options.meta);\n }\n\n return new WinstonLogger(logger, redacter.add);\n }\n\n /**\n * Creates a winston log formatter for redacting secrets.\n */\n static redacter(): {\n format: Format;\n add: (redactions: Iterable<string>) => void;\n } {\n const redactionSet = new Set<string>();\n\n let redactionPattern: RegExp | undefined = undefined;\n\n return {\n format: format((obj: TransformableInfo) => {\n if (!redactionPattern || !obj) {\n return obj;\n }\n\n if (typeof obj[MESSAGE] === 'string') {\n obj[MESSAGE] = obj[MESSAGE].replace(redactionPattern, '***');\n }\n\n return obj;\n })(),\n add(newRedactions) {\n let added = 0;\n for (const redactionToTrim of newRedactions) {\n // Skip null or undefined values\n if (redactionToTrim === null || redactionToTrim === undefined) {\n continue;\n }\n // Trimming the string ensures that we don't accdentally get extra\n // newlines or other whitespace interfering with the redaction; this\n // can happen for example when using string literals in yaml\n const redaction = redactionToTrim.trim();\n // Exclude secrets that are empty or just one character in length. These\n // typically mean that you are running local dev or tests, or using the\n // --lax flag which sets things to just 'x'.\n if (redaction.length <= 1) {\n continue;\n }\n if (!redactionSet.has(redaction)) {\n redactionSet.add(redaction);\n added += 1;\n }\n }\n if (added > 0) {\n const redactions = Array.from(redactionSet)\n .map(r => escapeRegExp(r))\n .join('|');\n redactionPattern = new RegExp(`(${redactions})`, 'g');\n }\n },\n };\n }\n\n /**\n * Creates a pretty printed winston log formatter.\n */\n static colorFormat(): Format {\n const colorizer = format.colorize();\n\n return format.combine(\n format.timestamp(),\n format.colorize({\n colors: {\n timestamp: 'dim',\n prefix: 'blue',\n field: 'cyan',\n debug: 'grey',\n },\n }),\n format.printf((info: TransformableInfo) => {\n const { timestamp, plugin, service } = info;\n const message = info[MESSAGE];\n const level = info[LEVEL];\n const fields = info[SPLAT];\n const prefix = plugin || service;\n const timestampColor = colorizer.colorize(\n 'timestamp',\n String(timestamp),\n );\n const prefixColor = colorizer.colorize('prefix', String(prefix));\n\n const extraFields = Object.entries(fields as any)\n .map(\n ([key, value]) =>\n `${colorizer.colorize('field', `${key}`)}=${value}`,\n )\n .join(' ');\n\n return `${timestampColor} ${prefixColor} ${level} ${message} ${extraFields}`;\n }),\n );\n }\n\n private constructor(\n winston: Logger,\n addRedactions?: (redactions: Iterable<string>) => void,\n ) {\n this.#winston = winston;\n this.#addRedactions = addRedactions;\n }\n\n error(message: string, meta?: JsonObject): void {\n this.#winston.error(message, meta);\n }\n\n warn(message: string, meta?: JsonObject): void {\n this.#winston.warn(message, meta);\n }\n\n info(message: string, meta?: JsonObject): void {\n this.#winston.info(message, meta);\n }\n\n debug(message: string, meta?: JsonObject): void {\n this.#winston.debug(message, meta);\n }\n\n child(meta: JsonObject): LoggerService {\n return new WinstonLogger(this.#winston.child(meta));\n }\n\n addRedactions(redactions: Iterable<string>) {\n this.#addRedactions?.(redactions);\n }\n}\n"],"names":["Transport","MESSAGE","LEVEL","createLogger","format","transports","SPLAT"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"logger.cjs.js","sources":["../../../src/scaffolder/tasks/logger.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n LoggerService,\n RootLoggerService,\n} from '@backstage/backend-plugin-api';\nimport { JsonObject } from '@backstage/types';\nimport { Format, TransformableInfo } from 'logform';\nimport Transport, { TransportStreamOptions } from 'winston-transport';\nimport { Logger, format, createLogger, transports } from 'winston';\nimport { LEVEL, MESSAGE, SPLAT } from 'triple-beam';\nimport { TaskContext } from '@backstage/plugin-scaffolder-node';\nimport type { ErrorLike } from '@backstage/errors';\nimport _ from 'lodash';\n\n/**\n * Escapes a given string to be used inside a RegExp.\n *\n * Taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions\n */\nconst escapeRegExp = (text: string) => {\n return text.replace(/[.*+?^${}(\\)|[\\]\\\\]/g, '\\\\$&');\n};\n\ninterface WinstonLoggerOptions {\n meta?: JsonObject;\n level: string;\n format: Format;\n transports: Transport[];\n}\n\n// This is a workaround for being able to preserve the log format of the root logger.\n// Will revisit all of this implementation once we can break the router to use only `LoggerService`.\nexport class BackstageLoggerTransport extends Transport {\n private readonly backstageLogger: LoggerService;\n private readonly taskContext: TaskContext;\n private readonly stepId: string;\n\n constructor(\n backstageLogger: LoggerService,\n taskContext: TaskContext,\n stepId: string,\n opts?: TransportStreamOptions,\n ) {\n super(opts);\n this.backstageLogger = backstageLogger;\n this.taskContext = taskContext;\n this.stepId = stepId;\n }\n\n log(info: TransformableInfo, callback: VoidFunction) {\n if (typeof info !== 'object' || info === null) {\n callback();\n return;\n }\n\n const message = info[MESSAGE];\n const level = info[LEVEL];\n\n switch (level) {\n case 'error':\n this.backstageLogger.error(String(message));\n break;\n case 'warn':\n this.backstageLogger.warn(String(message));\n break;\n case 'info':\n this.backstageLogger.info(String(message));\n break;\n case 'debug':\n this.backstageLogger.debug(String(message));\n break;\n default:\n this.backstageLogger.info(String(message));\n break;\n }\n\n this.taskContext.emitLog(String(message), { stepId: this.stepId });\n callback();\n }\n}\n\nexport class WinstonLogger implements RootLoggerService {\n #winston: Logger;\n #addRedactions?: (redactions: Iterable<string>) => void;\n #redact?: (value: string) => string;\n #redactError?: (error: unknown) => ErrorLike;\n\n /**\n * Creates a {@link WinstonLogger} instance.\n */\n static create(options: WinstonLoggerOptions): WinstonLogger {\n const redacter = WinstonLogger.redacter();\n\n let logger = createLogger({\n level: options.level,\n format: format.combine(options.format, redacter.format),\n transports: options.transports ?? new transports.Console(),\n });\n\n if (options.meta) {\n logger = logger.child(options.meta);\n }\n\n return new WinstonLogger(\n logger,\n redacter.add,\n redacter.redact,\n redacter.redactError,\n );\n }\n\n /**\n * Creates a winston log formatter for redacting secrets.\n */\n static redacter(): {\n format: Format;\n add: (redactions: Iterable<string>) => void;\n redact: (value: string) => string;\n redactError: (error: unknown) => ErrorLike;\n } {\n const redactionSet = new Set<string>();\n\n let redactionPattern: RegExp | undefined = undefined;\n\n const redact = (value: string) => {\n if (!redactionPattern) {\n return value;\n }\n\n const ranges = Array.from(value.matchAll(redactionPattern), match => ({\n start: match.index,\n end: match.index + match[1].length,\n }));\n if (ranges.length === 0) {\n return value;\n }\n\n const mergedRanges: { start: number; end: number }[] = [];\n for (const range of ranges) {\n const previous = mergedRanges.at(-1);\n if (previous && range.start < previous.end) {\n previous.end = Math.max(previous.end, range.end);\n } else {\n mergedRanges.push(range);\n }\n }\n\n let result = '';\n let cursor = 0;\n for (const range of mergedRanges) {\n result += `${value.slice(cursor, range.start)}***`;\n cursor = range.end;\n }\n return result + value.slice(cursor);\n };\n\n const createSanitizedError = (\n name = 'Error',\n message = 'Task failed',\n stack?: string,\n ): ErrorLike => {\n const sanitizedError = new Error(message) as ErrorLike;\n sanitizedError.name = name;\n if (stack !== undefined) {\n sanitizedError.stack = stack;\n }\n return sanitizedError;\n };\n\n const createUnknownError = (value: unknown): ErrorLike => {\n try {\n return createSanitizedError(\n 'Error',\n redact(`unknown error '${String(value)}'`),\n );\n } catch {\n return createSanitizedError(\n 'Error',\n `unknown error of type '${typeof value}'`,\n );\n }\n };\n\n const redactError = (error: unknown): ErrorLike => {\n if (\n (typeof error !== 'object' || error === null) &&\n typeof error !== 'function'\n ) {\n return typeof error === 'string'\n ? createSanitizedError('Error', redact(error))\n : createUnknownError(error);\n }\n\n const errorLike = error as Partial<ErrorLike>;\n let originalName: unknown;\n let originalMessage: unknown;\n let originalStack: unknown;\n\n try {\n originalName = errorLike.name;\n originalMessage = errorLike.message;\n originalStack = errorLike.stack;\n } catch {\n return createSanitizedError();\n }\n\n if (\n typeof originalName !== 'string' ||\n !originalName ||\n typeof originalMessage !== 'string'\n ) {\n return createUnknownError(error);\n }\n\n const name = redact(originalName);\n const message = redact(originalMessage);\n const stack =\n typeof originalStack === 'string' ? redact(originalStack) : undefined;\n\n return createSanitizedError(name, message, stack);\n };\n\n return {\n format: format((obj: TransformableInfo) => {\n if (!redactionPattern || !obj) {\n return obj;\n }\n\n if (typeof obj[MESSAGE] === 'string') {\n obj[MESSAGE] = redact(obj[MESSAGE]);\n }\n\n return obj;\n })(),\n add(newRedactions) {\n let added = 0;\n for (const redactionToTrim of newRedactions) {\n // Skip null or undefined values\n if (redactionToTrim === null || redactionToTrim === undefined) {\n continue;\n }\n // Trimming the string ensures that we don't accdentally get extra\n // newlines or other whitespace interfering with the redaction; this\n // can happen for example when using string literals in yaml\n const redaction = redactionToTrim.trim();\n // Exclude secrets that are empty or just one character in length. These\n // typically mean that you are running local dev or tests, or using the\n // --lax flag which sets things to just 'x'.\n if (redaction.length <= 1) {\n continue;\n }\n if (!redactionSet.has(redaction)) {\n redactionSet.add(redaction);\n added += 1;\n }\n }\n if (added > 0) {\n const redactions = Array.from(redactionSet)\n .sort((a, b) => b.length - a.length)\n .map(r => escapeRegExp(r))\n .join('|');\n redactionPattern = new RegExp(`(?=(${redactions}))`, 'g');\n }\n },\n redact,\n redactError,\n };\n }\n\n /**\n * Creates a pretty printed winston log formatter.\n */\n static colorFormat(): Format {\n const colorizer = format.colorize();\n\n return format.combine(\n format.timestamp(),\n format.colorize({\n colors: {\n timestamp: 'dim',\n prefix: 'blue',\n field: 'cyan',\n debug: 'grey',\n },\n }),\n format.printf((info: TransformableInfo) => {\n const { timestamp, plugin, service } = info;\n const message = info[MESSAGE];\n const level = info[LEVEL];\n const fields = info[SPLAT];\n const prefix = plugin || service;\n const timestampColor = colorizer.colorize(\n 'timestamp',\n String(timestamp),\n );\n const prefixColor = colorizer.colorize('prefix', String(prefix));\n\n const extraFields = Object.entries(fields as any)\n .map(\n ([key, value]) =>\n `${colorizer.colorize('field', `${key}`)}=${value}`,\n )\n .join(' ');\n\n return `${timestampColor} ${prefixColor} ${level} ${message} ${extraFields}`;\n }),\n );\n }\n\n private constructor(\n winston: Logger,\n addRedactions?: (redactions: Iterable<string>) => void,\n redact?: (value: string) => string,\n redactError?: (error: unknown) => ErrorLike,\n ) {\n this.#winston = winston;\n this.#addRedactions = addRedactions;\n this.#redact = redact;\n this.#redactError = redactError;\n }\n\n error(message: string, meta?: JsonObject): void {\n this.#winston.error(message, meta);\n }\n\n warn(message: string, meta?: JsonObject): void {\n this.#winston.warn(message, meta);\n }\n\n info(message: string, meta?: JsonObject): void {\n this.#winston.info(message, meta);\n }\n\n debug(message: string, meta?: JsonObject): void {\n this.#winston.debug(message, meta);\n }\n\n child(meta: JsonObject): LoggerService {\n return new WinstonLogger(\n this.#winston.child(meta),\n this.#addRedactions,\n this.#redact,\n this.#redactError,\n );\n }\n\n addRedactions(redactions: Iterable<string>) {\n this.#addRedactions?.(redactions);\n }\n\n redact(value: string) {\n return this.#redact?.(value) ?? value;\n }\n\n redactError(error: unknown): ErrorLike {\n return (\n this.#redactError?.(error) ?? (new Error('Task failed') as ErrorLike)\n );\n }\n}\n"],"names":["Transport","MESSAGE","LEVEL","createLogger","format","transports","SPLAT"],"mappings":"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"}
|
|
@@ -492,12 +492,6 @@ const spec = {
|
|
|
492
492
|
},
|
|
493
493
|
createdBy: {
|
|
494
494
|
type: "string"
|
|
495
|
-
},
|
|
496
|
-
secrets: {
|
|
497
|
-
$ref: "#/components/schemas/TaskSecrets"
|
|
498
|
-
},
|
|
499
|
-
state: {
|
|
500
|
-
$ref: "#/components/schemas/JsonObject"
|
|
501
495
|
}
|
|
502
496
|
},
|
|
503
497
|
required: ["id", "spec", "status", "createdAt"],
|
|
@@ -802,6 +796,9 @@ const spec = {
|
|
|
802
796
|
}
|
|
803
797
|
}
|
|
804
798
|
}
|
|
799
|
+
},
|
|
800
|
+
"400": {
|
|
801
|
+
$ref: "#/components/responses/ErrorResponse"
|
|
805
802
|
}
|
|
806
803
|
},
|
|
807
804
|
security: [
|
|
@@ -1010,6 +1007,9 @@ const spec = {
|
|
|
1010
1007
|
}
|
|
1011
1008
|
}
|
|
1012
1009
|
}
|
|
1010
|
+
},
|
|
1011
|
+
"409": {
|
|
1012
|
+
$ref: "#/components/responses/ErrorResponse"
|
|
1013
1013
|
}
|
|
1014
1014
|
},
|
|
1015
1015
|
security: [
|