@backstage/plugin-scaffolder-backend 3.4.1-next.0 → 3.5.0-next.1
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 +16 -0
- package/dist/actions/listScaffolderTasksAction.cjs.js +15 -3
- package/dist/actions/listScaffolderTasksAction.cjs.js.map +1 -1
- package/dist/scaffolder/dryrun/createDryRunner.cjs.js +2 -2
- package/dist/scaffolder/dryrun/createDryRunner.cjs.js.map +1 -1
- package/dist/scaffolder/tasks/DatabaseTaskStore.cjs.js +2 -2
- package/dist/scaffolder/tasks/DatabaseTaskStore.cjs.js.map +1 -1
- package/dist/scaffolder/tasks/NunjucksWorkflowRunner.cjs.js +70 -10
- package/dist/scaffolder/tasks/NunjucksWorkflowRunner.cjs.js.map +1 -1
- package/dist/service/router.cjs.js +2 -2
- package/dist/service/router.cjs.js.map +1 -1
- package/package.json +8 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @backstage/plugin-scaffolder-backend
|
|
2
2
|
|
|
3
|
+
## 3.5.0-next.1
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 77bee9f: Updated the `list-scaffolder-tasks` action to support the new "status" filter parameter, allowing the action to return tasks matching a specific status.
|
|
8
|
+
- 07e08be: Added `always()` and `failure()` status check functions for scaffolder steps. These functions can be used in the if field of a step to control execution after failures. `always()` ensures a step runs regardless of previous step outcomes, while `failure()` runs a step only when a previous step has failed.
|
|
9
|
+
|
|
10
|
+
### Patch Changes
|
|
11
|
+
|
|
12
|
+
- e9b78e9: Removed the `uuid` dependency and replaced usage with the built-in `crypto.randomUUID()`.
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
- @backstage/catalog-model@1.8.1-next.1
|
|
15
|
+
- @backstage/plugin-catalog-node@2.2.1-next.1
|
|
16
|
+
- @backstage/plugin-scaffolder-node@0.13.3-next.1
|
|
17
|
+
- @backstage/plugin-permission-common@0.9.9-next.1
|
|
18
|
+
|
|
3
19
|
## 3.4.1-next.0
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
|
@@ -20,7 +20,7 @@ This allows you to list scaffolder tasks that have been created.
|
|
|
20
20
|
Each task has a unique id, specification, and status (one of open, processing, completed, failed, cancelled, skipped).
|
|
21
21
|
Each task includes a timestamp for when it was created, and an optional last heartbeat timestamp indicating the most recent activity.
|
|
22
22
|
Set owned to true to return only tasks created by the current user; omit or set to false for all tasks the credentials can see.
|
|
23
|
-
Pagination is supported via limit and offset.
|
|
23
|
+
Filtering by one or multiple statuses is supported. Pagination is supported via limit and offset.
|
|
24
24
|
`,
|
|
25
25
|
schema: {
|
|
26
26
|
input: (z) => z.object({
|
|
@@ -28,7 +28,18 @@ Pagination is supported via limit and offset.
|
|
|
28
28
|
"If true, return only tasks created by the current user. Requires a user identity."
|
|
29
29
|
),
|
|
30
30
|
limit: z.number().int().min(1).max(1e3).describe("The maximum number of tasks to return for pagination").optional(),
|
|
31
|
-
offset: z.number().int().min(0).describe("The offset to start from for pagination").optional()
|
|
31
|
+
offset: z.number().int().min(0).describe("The offset to start from for pagination").optional(),
|
|
32
|
+
status: (() => {
|
|
33
|
+
const statusEnum = z.enum([
|
|
34
|
+
"open",
|
|
35
|
+
"processing",
|
|
36
|
+
"completed",
|
|
37
|
+
"failed",
|
|
38
|
+
"cancelled",
|
|
39
|
+
"skipped"
|
|
40
|
+
]);
|
|
41
|
+
return z.union([statusEnum, z.array(statusEnum).nonempty()]).optional().describe("Filter tasks by status, or an array of statuses");
|
|
42
|
+
})()
|
|
32
43
|
}),
|
|
33
44
|
output: (z) => z.object({
|
|
34
45
|
tasks: z.array(
|
|
@@ -56,7 +67,8 @@ Pagination is supported via limit and offset.
|
|
|
56
67
|
{
|
|
57
68
|
createdBy,
|
|
58
69
|
limit: input.limit,
|
|
59
|
-
offset: input.offset
|
|
70
|
+
offset: input.offset,
|
|
71
|
+
status: input.status
|
|
60
72
|
},
|
|
61
73
|
{ credentials }
|
|
62
74
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"listScaffolderTasksAction.cjs.js","sources":["../../src/actions/listScaffolderTasksAction.ts"],"sourcesContent":["/*\n * Copyright 2025 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 { ActionsRegistryService } from '@backstage/backend-plugin-api/alpha';\nimport { AuthService } from '@backstage/backend-plugin-api';\nimport { NotAllowedError } from '@backstage/errors';\nimport { ScaffolderService } from '@backstage/plugin-scaffolder-node';\n\nexport const createListScaffolderTasksAction = ({\n actionsRegistry,\n auth,\n scaffolderService,\n}: {\n actionsRegistry: ActionsRegistryService;\n auth: AuthService;\n scaffolderService: ScaffolderService;\n}) => {\n actionsRegistry.register({\n name: 'list-scaffolder-tasks',\n title: 'List Scaffolder Tasks',\n attributes: {\n destructive: false,\n readOnly: true,\n idempotent: true,\n },\n description: `\nThis allows you to list scaffolder tasks that have been created.\nEach task has a unique id, specification, and status (one of open, processing, completed, failed, cancelled, skipped).\nEach task includes a timestamp for when it was created, and an optional last heartbeat timestamp indicating the most recent activity.\nSet owned to true to return only tasks created by the current user; omit or set to false for all tasks the credentials can see.\
|
|
1
|
+
{"version":3,"file":"listScaffolderTasksAction.cjs.js","sources":["../../src/actions/listScaffolderTasksAction.ts"],"sourcesContent":["/*\n * Copyright 2025 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 { ActionsRegistryService } from '@backstage/backend-plugin-api/alpha';\nimport { AuthService } from '@backstage/backend-plugin-api';\nimport { NotAllowedError } from '@backstage/errors';\nimport { ScaffolderService } from '@backstage/plugin-scaffolder-node';\n\nexport const createListScaffolderTasksAction = ({\n actionsRegistry,\n auth,\n scaffolderService,\n}: {\n actionsRegistry: ActionsRegistryService;\n auth: AuthService;\n scaffolderService: ScaffolderService;\n}) => {\n actionsRegistry.register({\n name: 'list-scaffolder-tasks',\n title: 'List Scaffolder Tasks',\n attributes: {\n destructive: false,\n readOnly: true,\n idempotent: true,\n },\n description: `\nThis allows you to list scaffolder tasks that have been created.\nEach task has a unique id, specification, and status (one of open, processing, completed, failed, cancelled, skipped).\nEach task includes a timestamp for when it was created, and an optional last heartbeat timestamp indicating the most recent activity.\nSet owned to true to return only tasks created by the current user; omit or set to false for all tasks the credentials can see.\nFiltering by one or multiple statuses is supported. Pagination is supported via limit and offset.\n `,\n schema: {\n input: z =>\n z.object({\n owned: z\n .boolean()\n .optional()\n .default(false)\n .describe(\n 'If true, return only tasks created by the current user. Requires a user identity.',\n ),\n limit: z\n .number()\n .int()\n .min(1)\n .max(1000)\n .describe('The maximum number of tasks to return for pagination')\n .optional(),\n offset: z\n .number()\n .int()\n .min(0)\n .describe('The offset to start from for pagination')\n .optional(),\n status: (() => {\n const statusEnum = z.enum([\n 'open',\n 'processing',\n 'completed',\n 'failed',\n 'cancelled',\n 'skipped',\n ]);\n return z\n .union([statusEnum, z.array(statusEnum).nonempty()])\n .optional()\n .describe('Filter tasks by status, or an array of statuses');\n })(),\n }),\n output: z =>\n z\n .object({\n tasks: z\n .array(\n z.object({\n id: z.string().describe('The task identifier'),\n spec: z.unknown().describe('The task specification'),\n status: z\n .string()\n .describe(\n 'Task status: open, processing, completed, failed, cancelled, or skipped',\n ),\n createdAt: z\n .string()\n .describe('Timestamp when the task was created'),\n lastHeartbeatAt: z\n .string()\n .optional()\n .describe('Timestamp of the last heartbeat'),\n }),\n )\n .describe('The list of scaffolder tasks'),\n totalTasks: z\n .number()\n .describe('Total number of tasks matching the filter'),\n })\n .describe('Object containing a tasks array and totalTasks count'),\n },\n action: async ({ input, credentials }) => {\n if (input.owned && !auth.isPrincipal(credentials, 'user')) {\n throw new NotAllowedError(\n 'Filtering by owned tasks requires a user identity.',\n );\n }\n\n const createdBy =\n input.owned && auth.isPrincipal(credentials, 'user')\n ? credentials.principal.userEntityRef\n : undefined;\n\n const { items, totalItems } = await scaffolderService.listTasks(\n {\n createdBy,\n limit: input.limit,\n offset: input.offset,\n status: input.status,\n },\n { credentials },\n );\n\n return {\n output: {\n tasks: items.map(task => ({\n id: task.id,\n spec: task.spec,\n status: task.status,\n createdAt: task.createdAt,\n lastHeartbeatAt: task.lastHeartbeatAt,\n })),\n totalTasks: totalItems,\n },\n };\n },\n });\n};\n"],"names":["NotAllowedError"],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ var pluginScaffolderNode = require('@backstage/plugin-scaffolder-node');
|
|
|
4
4
|
var fs = require('fs-extra');
|
|
5
5
|
var path = require('node:path');
|
|
6
6
|
var node_url = require('node:url');
|
|
7
|
-
var
|
|
7
|
+
var node_crypto = require('node:crypto');
|
|
8
8
|
var NunjucksWorkflowRunner = require('../tasks/NunjucksWorkflowRunner.cjs.js');
|
|
9
9
|
var DecoratedActionsRegistry = require('./DecoratedActionsRegistry.cjs.js');
|
|
10
10
|
|
|
@@ -37,7 +37,7 @@ function createDryRunner(options) {
|
|
|
37
37
|
}
|
|
38
38
|
const basePath = node_url.fileURLToPath(new URL(baseUrl));
|
|
39
39
|
const contentsPath = path__default.default.dirname(basePath);
|
|
40
|
-
const dryRunId =
|
|
40
|
+
const dryRunId = node_crypto.randomUUID();
|
|
41
41
|
const log = new Array();
|
|
42
42
|
try {
|
|
43
43
|
await pluginScaffolderNode.deserializeDirectoryContents(contentsPath, input.directoryContents);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createDryRunner.cjs.js","sources":["../../../src/scaffolder/dryrun/createDryRunner.ts"],"sourcesContent":["/*\n * Copyright 2022 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 {\n AuditorService,\n BackstageCredentials,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport type { MetricsService } from '@backstage/backend-plugin-api/alpha';\nimport type { UserEntity } from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { PermissionEvaluator } from '@backstage/plugin-permission-common';\nimport {\n ScaffolderTaskStatus,\n TaskSpec,\n TemplateInfo,\n} from '@backstage/plugin-scaffolder-common';\nimport {\n createTemplateAction,\n deserializeDirectoryContents,\n SerializedFile,\n serializeDirectoryContents,\n TaskSecrets,\n TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport { JsonObject } from '@backstage/types';\nimport fs from 'fs-extra';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport {
|
|
1
|
+
{"version":3,"file":"createDryRunner.cjs.js","sources":["../../../src/scaffolder/dryrun/createDryRunner.ts"],"sourcesContent":["/*\n * Copyright 2022 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 {\n AuditorService,\n BackstageCredentials,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport type { MetricsService } from '@backstage/backend-plugin-api/alpha';\nimport type { UserEntity } from '@backstage/catalog-model';\nimport { Config } from '@backstage/config';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { PermissionEvaluator } from '@backstage/plugin-permission-common';\nimport {\n ScaffolderTaskStatus,\n TaskSpec,\n TemplateInfo,\n} from '@backstage/plugin-scaffolder-common';\nimport {\n createTemplateAction,\n deserializeDirectoryContents,\n SerializedFile,\n serializeDirectoryContents,\n TaskSecrets,\n TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport { JsonObject } from '@backstage/types';\nimport fs from 'fs-extra';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { randomUUID as uuid } from 'node:crypto';\nimport { NunjucksWorkflowRunner } from '../tasks/NunjucksWorkflowRunner';\nimport { DecoratedActionsRegistry } from './DecoratedActionsRegistry';\nimport { TemplateActionRegistry } from '../actions';\n\ninterface DryRunInput {\n spec: TaskSpec;\n templateInfo: TemplateInfo;\n secrets?: TaskSecrets;\n directoryContents: SerializedFile[];\n credentials: BackstageCredentials;\n user?: {\n entity?: UserEntity;\n ref?: string;\n };\n}\n\ninterface DryRunResult {\n log: Array<{\n body: {\n message: string;\n stepId?: string;\n status?: ScaffolderTaskStatus;\n };\n }>;\n directoryContents: SerializedFile[];\n output: JsonObject;\n}\n\n/** @internal */\nexport type TemplateTesterCreateOptions = {\n logger: LoggerService;\n auditor?: AuditorService;\n integrations: ScmIntegrations;\n actionRegistry: TemplateActionRegistry;\n workingDirectory: string;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n additionalTemplateGlobals?: Record<string, TemplateGlobal>;\n permissions?: PermissionEvaluator;\n config?: Config;\n metrics: MetricsService;\n};\n\n/**\n * Executes a dry-run of the provided template.\n *\n * The provided content will be extracted into a temporary directory\n * which is then use as the base for any relative file fetch paths.\n *\n * @internal\n */\nexport function createDryRunner(options: TemplateTesterCreateOptions) {\n return async function dryRun(input: DryRunInput): Promise<DryRunResult> {\n let contentPromise;\n\n const workflowRunner = new NunjucksWorkflowRunner({\n ...options,\n actionRegistry: new DecoratedActionsRegistry(options.actionRegistry, [\n createTemplateAction({\n id: 'dry-run:extract',\n supportsDryRun: true,\n async handler(ctx) {\n contentPromise = serializeDirectoryContents(ctx.workspacePath);\n await contentPromise.catch(() => {});\n },\n }),\n ]),\n config: options.config,\n });\n\n // Extracting contentsPath and dryRunId from the baseUrl\n const baseUrl = input.templateInfo.baseUrl;\n if (!baseUrl) {\n throw new Error('baseUrl is required');\n }\n const basePath = fileURLToPath(new URL(baseUrl));\n const contentsPath = path.dirname(basePath);\n const dryRunId = uuid();\n\n const log = new Array<{\n body: {\n message: string;\n stepId?: string;\n status?: ScaffolderTaskStatus;\n };\n }>();\n\n try {\n await deserializeDirectoryContents(contentsPath, input.directoryContents);\n\n const abortSignal = new AbortController().signal;\n const result = await workflowRunner.execute({\n taskId: dryRunId,\n spec: {\n ...input.spec,\n steps: [\n ...input.spec.steps,\n {\n id: dryRunId,\n name: 'dry-run:extract',\n action: 'dry-run:extract',\n },\n ],\n templateInfo: input.templateInfo,\n },\n secrets: input.secrets,\n getInitiatorCredentials: () => Promise.resolve(input.credentials),\n // No need to update this at the end of the run, so just hard-code it\n done: false,\n isDryRun: true,\n getWorkspaceName: async () => `dry-run-${dryRunId}`,\n cancelSignal: abortSignal,\n async emitLog(message: string, logMetadata?: JsonObject) {\n if (logMetadata?.stepId === dryRunId) {\n return;\n }\n log.push({\n body: {\n ...logMetadata,\n message,\n },\n });\n },\n complete: async () => {\n throw new Error('Not implemented');\n },\n });\n\n if (!contentPromise) {\n throw new Error('Content extraction step was skipped');\n }\n const directoryContents = await contentPromise;\n\n return {\n log,\n directoryContents,\n output: result.output,\n };\n } finally {\n await fs.remove(contentsPath);\n }\n };\n}\n"],"names":["NunjucksWorkflowRunner","DecoratedActionsRegistry","createTemplateAction","serializeDirectoryContents","fileURLToPath","path","uuid","deserializeDirectoryContents","fs"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
4
4
|
var errors = require('@backstage/errors');
|
|
5
|
-
var
|
|
5
|
+
var node_crypto = require('node:crypto');
|
|
6
6
|
var luxon = require('luxon');
|
|
7
7
|
var taskRecoveryHelper = require('./taskRecoveryHelper.cjs.js');
|
|
8
8
|
var dbUtil = require('./dbUtil.cjs.js');
|
|
@@ -203,7 +203,7 @@ class DatabaseTaskStore {
|
|
|
203
203
|
};
|
|
204
204
|
}
|
|
205
205
|
async createTask(options) {
|
|
206
|
-
const taskId =
|
|
206
|
+
const taskId = node_crypto.randomUUID();
|
|
207
207
|
await this.db("tasks").insert({
|
|
208
208
|
id: taskId,
|
|
209
209
|
spec: JSON.stringify(options.spec),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatabaseTaskStore.cjs.js","sources":["../../../src/scaffolder/tasks/DatabaseTaskStore.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 { JsonObject } from '@backstage/types';\nimport {\n DatabaseService,\n resolvePackagePath,\n} from '@backstage/backend-plugin-api';\nimport { ConflictError, NotFoundError } from '@backstage/errors';\nimport { Knex } from 'knex';\nimport { v4 as uuid } from 'uuid';\nimport {\n TaskStore,\n TaskStoreCreateTaskOptions,\n TaskStoreCreateTaskResult,\n TaskStoreEmitOptions,\n TaskStoreListEventsOptions,\n TaskStoreRecoverTaskOptions,\n TaskStoreShutDownTaskOptions,\n} from './types';\nimport {\n SerializedTask,\n SerializedTaskEvent,\n TaskEventType,\n TaskFilter,\n TaskSecrets,\n TaskStatus,\n} from '@backstage/plugin-scaffolder-node';\nimport { DateTime, Duration } from 'luxon';\nimport { TaskRecovery, TaskSpec } from '@backstage/plugin-scaffolder-common';\nimport { trimEventsTillLastRecovery } from './taskRecoveryHelper';\nimport { intervalFromNowTill } from './dbUtil';\nimport {\n restoreWorkspace,\n serializeWorkspace,\n} from '@backstage/plugin-scaffolder-node/alpha';\nimport { flattenParams } from '../../service/helpers';\nimport { EventsService } from '@backstage/plugin-events-node';\nimport { PermissionCriteria } from '@backstage/plugin-permission-common';\nimport {\n isAndCriteria,\n isNotCriteria,\n isOrCriteria,\n} from '@backstage/plugin-permission-node';\nimport { TaskFilters } from '@backstage/plugin-scaffolder-node';\nimport { compact } from 'lodash';\n\nconst migrationsDir = resolvePackagePath(\n '@backstage/plugin-scaffolder-backend',\n 'migrations',\n);\n\nexport type RawDbTaskRow = {\n id: string;\n spec: string;\n status: TaskStatus;\n state?: string;\n last_heartbeat_at?: string;\n created_at: string;\n created_by: string | null;\n secrets?: string | null;\n workspace?: Buffer;\n};\n\nexport type RawDbTaskEventRow = {\n id: number;\n task_id: string;\n body: string;\n event_type: TaskEventType;\n created_at: string;\n};\n\n/**\n * DatabaseTaskStore\n */\nexport type DatabaseTaskStoreOptions = {\n database: DatabaseService | Knex;\n events?: EventsService;\n};\n\n/**\n * Type guard to help DatabaseTaskStore understand when database is DatabaseService vs. when database is a Knex instance.\n * */\nfunction isDatabaseService(\n opt: DatabaseService | Knex,\n): opt is DatabaseService {\n return (opt as DatabaseService).getClient !== undefined;\n}\n\nconst parseSqlDateToIsoString = <T>(input: T): T | string => {\n if (typeof input === 'string') {\n const parsed = DateTime.fromSQL(input, { zone: 'UTC' });\n if (!parsed.isValid) {\n throw new Error(\n `Failed to parse database timestamp '${input}', ${parsed.invalidReason}: ${parsed.invalidExplanation}`,\n );\n }\n return parsed.toISO()!;\n }\n\n return input;\n};\n\n/**\n * DatabaseTaskStore\n */\nexport class DatabaseTaskStore implements TaskStore {\n private readonly db: Knex;\n private readonly events?: EventsService;\n\n static async create(\n options: DatabaseTaskStoreOptions,\n ): Promise<DatabaseTaskStore> {\n const { database } = options;\n const client = await this.getClient(database);\n\n await this.runMigrations(database, client);\n\n return new DatabaseTaskStore(client, options.events);\n }\n\n private isRecoverableTask(spec: TaskSpec): boolean {\n return ['startOver'].includes(\n spec.EXPERIMENTAL_recovery?.EXPERIMENTAL_strategy ?? 'none',\n );\n }\n\n private parseSpec({ spec, id }: { spec: string; id: string }): TaskSpec {\n try {\n return JSON.parse(spec);\n } catch (error) {\n throw new Error(`Failed to parse spec of task '${id}', ${error}`);\n }\n }\n\n private parseTaskSecrets(taskRow: RawDbTaskRow): TaskSecrets | undefined {\n try {\n return taskRow.secrets ? JSON.parse(taskRow.secrets) : undefined;\n } catch (error) {\n throw new Error(\n `Failed to parse secrets of task '${taskRow.id}', ${error}`,\n );\n }\n }\n\n private static async getClient(\n database: DatabaseService | Knex,\n ): Promise<Knex> {\n if (isDatabaseService(database)) {\n return database.getClient();\n }\n\n return database;\n }\n\n private static async runMigrations(\n database: DatabaseService | Knex,\n client: Knex,\n ): Promise<void> {\n if (!isDatabaseService(database)) {\n await client.migrate.latest({\n directory: migrationsDir,\n });\n\n return;\n }\n\n if (!database.migrations?.skip) {\n await client.migrate.latest({\n directory: migrationsDir,\n });\n }\n }\n\n private constructor(client: Knex, events?: EventsService) {\n this.db = client;\n this.events = events;\n }\n\n private getState(task: RawDbTaskRow) {\n try {\n return task.state ? JSON.parse(task.state).state : undefined;\n } catch (error) {\n throw new Error(\n `Failed to parse state of the task '${task.id}', ${error}`,\n );\n }\n }\n\n private isTaskFilter(filter: any): filter is TaskFilter {\n return filter.hasOwnProperty('key');\n }\n\n private parseFilter(\n filter: PermissionCriteria<TaskFilters>,\n query: Knex.QueryBuilder,\n db: Knex,\n negate: boolean = false,\n ): Knex.QueryBuilder {\n if (isNotCriteria(filter)) {\n return this.parseFilter(filter.not, query, db, !negate);\n }\n\n if (this.isTaskFilter(filter)) {\n const values: string[] = compact(filter.values) ?? [];\n if (negate) {\n query.whereNotIn(filter.key, values);\n } else {\n query.whereIn(filter.key, values);\n }\n\n return query;\n }\n\n return query[negate ? 'andWhereNot' : 'andWhere'](subQuery => {\n if (isOrCriteria(filter)) {\n for (const subFilter of filter.anyOf ?? []) {\n subQuery.orWhere(subQueryInner =>\n this.parseFilter(subFilter, subQueryInner, db, false),\n );\n }\n } else if (isAndCriteria(filter)) {\n for (const subFilter of filter.allOf ?? []) {\n subQuery.andWhere(subQueryInner =>\n this.parseFilter(subFilter, subQueryInner, db, false),\n );\n }\n }\n });\n }\n\n async list(options: {\n createdBy?: string;\n status?: TaskStatus;\n filters?: {\n createdBy?: string | string[];\n status?: TaskStatus | TaskStatus[];\n };\n pagination?: {\n limit?: number;\n offset?: number;\n };\n order?: { order: 'asc' | 'desc'; field: string }[];\n permissionFilters?: PermissionCriteria<TaskFilters>;\n }): Promise<{ tasks: SerializedTask[]; totalTasks?: number }> {\n const { createdBy, status, pagination, order, filters, permissionFilters } =\n options ?? {};\n const queryBuilder = this.db<RawDbTaskRow & { count: number }>('tasks');\n\n const createdByValues = flattenParams<string>(\n createdBy,\n filters?.createdBy,\n );\n\n const combinedPermissionFilters:\n | PermissionCriteria<TaskFilters>\n | undefined =\n createdByValues.length > 0\n ? {\n allOf: [\n { key: 'created_by', values: createdByValues },\n ...(permissionFilters ? [permissionFilters] : []),\n ],\n }\n : permissionFilters;\n\n if (combinedPermissionFilters) {\n this.parseFilter(combinedPermissionFilters, queryBuilder, this.db);\n }\n\n if (status || filters?.status) {\n const arr: TaskStatus[] = flattenParams<TaskStatus>(\n status,\n filters?.status,\n );\n queryBuilder.whereIn('status', [...new Set(arr)]);\n }\n\n const countQuery = queryBuilder.clone();\n countQuery.count('tasks.id', { as: 'count' });\n\n if (order) {\n order.forEach(f => {\n queryBuilder.orderBy(f.field, f.order);\n });\n } else {\n queryBuilder.orderBy('created_at', 'desc');\n }\n\n if (pagination?.limit !== undefined) {\n queryBuilder.limit(pagination.limit);\n }\n\n if (pagination?.offset !== undefined) {\n queryBuilder.offset(pagination.offset);\n }\n\n const [results, [{ count }]] = await Promise.all([\n queryBuilder.select(),\n countQuery,\n ]);\n\n const tasks = results.map(result => ({\n id: result.id,\n spec: JSON.parse(result.spec),\n status: result.status,\n createdBy: result.created_by ?? undefined,\n lastHeartbeatAt: parseSqlDateToIsoString(result.last_heartbeat_at),\n createdAt: parseSqlDateToIsoString(result.created_at),\n }));\n\n return { tasks, totalTasks: count };\n }\n\n async getTask(taskId: string): Promise<SerializedTask> {\n const [result] = await this.db<RawDbTaskRow>('tasks')\n .where({ id: taskId })\n .select();\n if (!result) {\n throw new NotFoundError(`No task with id '${taskId}' found`);\n }\n try {\n return this.parseTaskRow(result);\n } catch (error) {\n throw new Error(`Failed to parse spec of task '${taskId}', ${error}`);\n }\n }\n\n private parseTaskRow(result: RawDbTaskRow): SerializedTask {\n const spec = JSON.parse(result.spec);\n const secrets = result.secrets ? JSON.parse(result.secrets) : undefined;\n const state = this.getState(result);\n\n return {\n id: result.id,\n spec,\n status: result.status,\n lastHeartbeatAt: parseSqlDateToIsoString(result.last_heartbeat_at),\n createdAt: parseSqlDateToIsoString(result.created_at),\n createdBy: result.created_by ?? undefined,\n secrets,\n state,\n };\n }\n\n async createTask(\n options: TaskStoreCreateTaskOptions,\n ): Promise<TaskStoreCreateTaskResult> {\n const taskId = uuid();\n await this.db<RawDbTaskRow>('tasks').insert({\n id: taskId,\n spec: JSON.stringify(options.spec),\n secrets: options.secrets ? JSON.stringify(options.secrets) : undefined,\n created_by: options.createdBy ?? null,\n status: 'open',\n });\n\n this.events?.publish({\n topic: 'scaffolder.task',\n eventPayload: {\n id: taskId,\n spec: options.spec,\n createdBy: options.createdBy,\n status: 'open',\n },\n });\n\n return { taskId };\n }\n\n async claimTask(): Promise<SerializedTask | undefined> {\n return this.db.transaction(async tx => {\n const [task] = await tx<RawDbTaskRow>('tasks')\n .where({\n status: 'open',\n })\n .limit(1)\n .select();\n\n if (!task) {\n return undefined;\n }\n\n const spec = this.parseSpec(task);\n\n const updateCount = await tx<RawDbTaskRow>('tasks')\n .where({ id: task.id, status: 'open' })\n .update({\n status: 'processing',\n last_heartbeat_at: this.db.fn.now(),\n // remove the secrets for non-recoverable tasks when moving to processing state.\n secrets: this.isRecoverableTask(spec) ? task.secrets : null,\n });\n\n if (updateCount < 1) {\n return undefined;\n }\n\n const ret: SerializedTask = {\n id: task.id,\n spec,\n status: 'processing',\n lastHeartbeatAt: task.last_heartbeat_at,\n createdAt: task.created_at,\n createdBy: task.created_by ?? undefined,\n state: this.getState(task),\n };\n\n this.events?.publish({\n topic: 'scaffolder.task',\n eventPayload: ret,\n });\n\n const secrets = this.parseTaskSecrets(task);\n return { ...ret, secrets };\n });\n }\n\n async heartbeatTask(taskId: string): Promise<void> {\n const updateCount = await this.db<RawDbTaskRow>('tasks')\n .where({ id: taskId, status: 'processing' })\n .update({\n last_heartbeat_at: this.db.fn.now(),\n });\n if (updateCount === 0) {\n throw new ConflictError(`No running task with taskId ${taskId} found`);\n }\n }\n\n async listStaleTasks(options: { timeoutS: number }): Promise<{\n tasks: { taskId: string; recovery?: TaskRecovery }[];\n }> {\n const { timeoutS } = options;\n const heartbeatInterval = intervalFromNowTill(timeoutS, this.db);\n const rawRows = await this.db<RawDbTaskRow>('tasks')\n .where('status', 'processing')\n .andWhere('last_heartbeat_at', '<=', heartbeatInterval);\n const tasks = rawRows.map(row => ({\n recovery: (JSON.parse(row.spec) as TaskSpec).EXPERIMENTAL_recovery,\n taskId: row.id,\n }));\n return { tasks };\n }\n\n async completeTask(options: {\n taskId: string;\n status: TaskStatus;\n eventBody: JsonObject;\n }): Promise<void> {\n const { taskId, status, eventBody } = options;\n\n let oldStatus: TaskStatus;\n if (['failed', 'completed', 'cancelled'].includes(status)) {\n oldStatus = 'processing';\n } else {\n throw new Error(\n `Invalid status update of run '${taskId}' to status '${status}'`,\n );\n }\n\n await this.db.transaction(async tx => {\n const [task] = await tx<RawDbTaskRow>('tasks')\n .where({\n id: taskId,\n })\n .limit(1)\n .select();\n\n const updateTask = async (criteria: {\n id: string;\n status?: TaskStatus;\n }) => {\n const updateCount = await tx<RawDbTaskRow>('tasks')\n .where(criteria)\n .update({\n status,\n secrets: null,\n });\n\n if (updateCount !== 1) {\n throw new ConflictError(\n `Failed to update status to '${status}' for taskId ${taskId}`,\n );\n }\n\n this.events?.publish({\n topic: 'scaffolder.task',\n eventPayload: {\n id: taskId,\n status: status,\n lastHeartbeatAt: task.last_heartbeat_at,\n createdAt: task.created_at,\n createdBy: task.created_by,\n state: this.getState(task),\n },\n });\n\n await tx<RawDbTaskEventRow>('task_events')\n .insert({\n task_id: taskId,\n event_type: 'completion',\n body: JSON.stringify(eventBody),\n })\n .returning('id');\n };\n\n if (status === 'cancelled') {\n await updateTask({\n id: taskId,\n });\n return;\n }\n\n if (task.status === 'cancelled') {\n return;\n }\n\n if (!task) {\n throw new Error(`No task with taskId ${taskId} found`);\n }\n if (task.status !== oldStatus) {\n throw new ConflictError(\n `Refusing to update status of run '${taskId}' to status '${status}' ` +\n `as it is currently '${task.status}', expected '${oldStatus}'`,\n );\n }\n\n await updateTask({\n id: taskId,\n status: oldStatus,\n });\n });\n }\n\n async emitLogEvent(\n options: TaskStoreEmitOptions<{ message: string } & JsonObject>,\n ): Promise<void> {\n const { taskId, body } = options;\n const serializedBody = JSON.stringify(body);\n await this.db<RawDbTaskEventRow>('task_events')\n .insert({\n task_id: taskId,\n event_type: 'log',\n body: serializedBody,\n })\n .returning('id');\n }\n\n async getTaskState({ taskId }: { taskId: string }): Promise<\n | {\n state: JsonObject;\n }\n | undefined\n > {\n const [result] = await this.db<RawDbTaskRow>('tasks')\n .where({ id: taskId })\n .select('state');\n return result.state ? JSON.parse(result.state) : undefined;\n }\n\n async saveTaskState(options: {\n taskId: string;\n state?: JsonObject;\n }): Promise<void> {\n if (options.state) {\n const serializedState = JSON.stringify({ state: options.state });\n await this.db<RawDbTaskRow>('tasks')\n .where({ id: options.taskId })\n .update({\n state: serializedState,\n });\n }\n }\n\n async listEvents(\n options: TaskStoreListEventsOptions,\n ): Promise<{ events: SerializedTaskEvent[] }> {\n const { isTaskRecoverable, taskId, after } = options;\n const rawEvents = await this.db<RawDbTaskEventRow>('task_events')\n .where({\n task_id: taskId,\n })\n .andWhere(builder => {\n if (typeof after === 'number') {\n builder.where('id', '>', after).orWhere('event_type', 'completion');\n }\n })\n .orderBy('id')\n .select();\n\n const events = rawEvents.map(event => {\n try {\n const body = JSON.parse(event.body) as SerializedTaskEvent['body'];\n return {\n id: Number(event.id),\n isTaskRecoverable,\n taskId,\n body,\n type: event.event_type,\n createdAt: parseSqlDateToIsoString(event.created_at),\n };\n } catch (error) {\n throw new Error(\n `Failed to parse event body from event taskId=${taskId} id=${event.id}, ${error}`,\n );\n }\n });\n\n return trimEventsTillLastRecovery(events);\n }\n\n async shutdownTask(options: TaskStoreShutDownTaskOptions): Promise<void> {\n const { taskId } = options;\n const message = `This task was marked as stale as it exceeded its timeout`;\n\n const statusStepEvents = (await this.listEvents({ taskId })).events.filter(\n ({ body }) => body?.stepId,\n );\n\n const completedSteps = statusStepEvents\n .filter(\n ({ body: { status } }) => status === 'failed' || status === 'completed',\n )\n .map(step => step.body.stepId);\n\n const hungProcessingSteps = statusStepEvents\n .filter(({ body: { status } }) => status === 'processing')\n .map(event => event.body.stepId)\n .filter(step => !completedSteps.includes(step));\n\n for (const step of hungProcessingSteps) {\n await this.emitLogEvent({\n taskId,\n body: {\n message,\n stepId: step,\n status: 'failed',\n },\n });\n }\n\n await this.completeTask({\n taskId,\n status: 'failed',\n eventBody: {\n message,\n },\n });\n }\n\n async rehydrateWorkspace(options: {\n taskId: string;\n targetPath: string;\n }): Promise<void> {\n const [result] = await this.db<RawDbTaskRow>('tasks')\n .where({ id: options.taskId })\n .select('workspace');\n\n await restoreWorkspace({\n path: options.targetPath,\n buffer: result.workspace,\n });\n }\n\n async cleanWorkspace({ taskId }: { taskId: string }): Promise<void> {\n await this.db('tasks').where({ id: taskId }).update({\n workspace: null,\n });\n }\n\n async serializeWorkspace(options: {\n path: string;\n taskId: string;\n }): Promise<void> {\n if (options.path) {\n const workspace = (await serializeWorkspace(options)).contents;\n await this.db<RawDbTaskRow>('tasks')\n .where({ id: options.taskId })\n .update({\n workspace,\n });\n }\n }\n\n async cancelTask(\n options: TaskStoreEmitOptions<{ message: string } & JsonObject>,\n ): Promise<void> {\n const { taskId, body } = options;\n const serializedBody = JSON.stringify(body);\n const [ret] = await this.db<RawDbTaskEventRow>('task_events')\n .insert({\n task_id: taskId,\n event_type: 'cancelled',\n body: serializedBody,\n })\n .returning('id');\n\n this.events?.publish({\n topic: 'scaffolder.task',\n eventPayload: {\n id: ret.id,\n taskId,\n status: 'cancelled',\n body,\n },\n });\n }\n\n async retryTask(options: {\n secrets?: TaskSecrets;\n taskId: string;\n }): Promise<void> {\n const { secrets, taskId } = options;\n\n await this.db.transaction(async tx => {\n const result = await tx<RawDbTaskRow>('tasks')\n .where('id', taskId)\n .update(\n {\n ...(secrets && { secrets: JSON.stringify(secrets) }),\n status: 'open',\n last_heartbeat_at: this.db.fn.now(),\n },\n ['id', 'spec'],\n );\n\n for (const { id, spec } of result) {\n const taskSpec = JSON.parse(spec as string) as TaskSpec;\n\n /**\n * Once task is picked up, all event types are replayed.\n * We have to remove cancelled or completion event_type as these are as actions for frontend to perform.\n * In contrary, we send 'recovered' event_type to reset the state on the frontend side.\n *\n */\n await tx<RawDbTaskEventRow>('task_events')\n .where('task_id', id)\n .andWhere(q => q.whereIn('event_type', ['cancelled', 'completion']))\n .del();\n\n await tx<RawDbTaskEventRow>('task_events').insert({\n task_id: id,\n event_type: 'recovered',\n body: JSON.stringify({\n recoverStrategy:\n taskSpec.EXPERIMENTAL_recovery?.EXPERIMENTAL_strategy ?? 'none',\n }),\n });\n }\n });\n }\n\n async recoverTasks(\n options: TaskStoreRecoverTaskOptions,\n ): Promise<{ ids: string[] }> {\n const taskIdsToRecover: string[] = [];\n const timeoutS = Duration.fromObject(options.timeout).as('seconds');\n\n await this.db.transaction(async tx => {\n const heartbeatInterval = intervalFromNowTill(timeoutS, this.db);\n\n const result = await tx<RawDbTaskRow>('tasks')\n .where('status', 'processing')\n .andWhere('last_heartbeat_at', '<=', heartbeatInterval)\n .update(\n {\n status: 'open',\n last_heartbeat_at: this.db.fn.now(),\n },\n ['id', 'spec'],\n );\n\n taskIdsToRecover.push(...result.map(i => i.id));\n\n for (const { id, spec } of result) {\n const taskSpec = JSON.parse(spec as string) as TaskSpec;\n const event = {\n recoverStrategy:\n taskSpec.EXPERIMENTAL_recovery?.EXPERIMENTAL_strategy ?? 'none',\n };\n const [ret] = await tx<RawDbTaskEventRow>('task_events')\n .insert({\n task_id: id,\n event_type: 'recovered',\n body: JSON.stringify(event),\n })\n .returning('id');\n\n this.events?.publish({\n topic: 'scaffolder.task',\n eventPayload: {\n id: ret.id,\n taskId: id,\n status: 'recovered',\n body: event,\n },\n });\n }\n });\n\n return { ids: taskIdsToRecover };\n }\n}\n"],"names":["resolvePackagePath","DateTime","isNotCriteria","compact","isOrCriteria","isAndCriteria","flattenParams","NotFoundError","uuid","ConflictError","intervalFromNowTill","trimEventsTillLastRecovery","restoreWorkspace","serializeWorkspace","Duration"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DatabaseTaskStore.cjs.js","sources":["../../../src/scaffolder/tasks/DatabaseTaskStore.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 { JsonObject } from '@backstage/types';\nimport {\n DatabaseService,\n resolvePackagePath,\n} from '@backstage/backend-plugin-api';\nimport { ConflictError, NotFoundError } from '@backstage/errors';\nimport { Knex } from 'knex';\nimport { randomUUID as uuid } from 'node:crypto';\nimport {\n TaskStore,\n TaskStoreCreateTaskOptions,\n TaskStoreCreateTaskResult,\n TaskStoreEmitOptions,\n TaskStoreListEventsOptions,\n TaskStoreRecoverTaskOptions,\n TaskStoreShutDownTaskOptions,\n} from './types';\nimport {\n SerializedTask,\n SerializedTaskEvent,\n TaskEventType,\n TaskFilter,\n TaskSecrets,\n TaskStatus,\n} from '@backstage/plugin-scaffolder-node';\nimport { DateTime, Duration } from 'luxon';\nimport { TaskRecovery, TaskSpec } from '@backstage/plugin-scaffolder-common';\nimport { trimEventsTillLastRecovery } from './taskRecoveryHelper';\nimport { intervalFromNowTill } from './dbUtil';\nimport {\n restoreWorkspace,\n serializeWorkspace,\n} from '@backstage/plugin-scaffolder-node/alpha';\nimport { flattenParams } from '../../service/helpers';\nimport { EventsService } from '@backstage/plugin-events-node';\nimport { PermissionCriteria } from '@backstage/plugin-permission-common';\nimport {\n isAndCriteria,\n isNotCriteria,\n isOrCriteria,\n} from '@backstage/plugin-permission-node';\nimport { TaskFilters } from '@backstage/plugin-scaffolder-node';\nimport { compact } from 'lodash';\n\nconst migrationsDir = resolvePackagePath(\n '@backstage/plugin-scaffolder-backend',\n 'migrations',\n);\n\nexport type RawDbTaskRow = {\n id: string;\n spec: string;\n status: TaskStatus;\n state?: string;\n last_heartbeat_at?: string;\n created_at: string;\n created_by: string | null;\n secrets?: string | null;\n workspace?: Buffer;\n};\n\nexport type RawDbTaskEventRow = {\n id: number;\n task_id: string;\n body: string;\n event_type: TaskEventType;\n created_at: string;\n};\n\n/**\n * DatabaseTaskStore\n */\nexport type DatabaseTaskStoreOptions = {\n database: DatabaseService | Knex;\n events?: EventsService;\n};\n\n/**\n * Type guard to help DatabaseTaskStore understand when database is DatabaseService vs. when database is a Knex instance.\n * */\nfunction isDatabaseService(\n opt: DatabaseService | Knex,\n): opt is DatabaseService {\n return (opt as DatabaseService).getClient !== undefined;\n}\n\nconst parseSqlDateToIsoString = <T>(input: T): T | string => {\n if (typeof input === 'string') {\n const parsed = DateTime.fromSQL(input, { zone: 'UTC' });\n if (!parsed.isValid) {\n throw new Error(\n `Failed to parse database timestamp '${input}', ${parsed.invalidReason}: ${parsed.invalidExplanation}`,\n );\n }\n return parsed.toISO()!;\n }\n\n return input;\n};\n\n/**\n * DatabaseTaskStore\n */\nexport class DatabaseTaskStore implements TaskStore {\n private readonly db: Knex;\n private readonly events?: EventsService;\n\n static async create(\n options: DatabaseTaskStoreOptions,\n ): Promise<DatabaseTaskStore> {\n const { database } = options;\n const client = await this.getClient(database);\n\n await this.runMigrations(database, client);\n\n return new DatabaseTaskStore(client, options.events);\n }\n\n private isRecoverableTask(spec: TaskSpec): boolean {\n return ['startOver'].includes(\n spec.EXPERIMENTAL_recovery?.EXPERIMENTAL_strategy ?? 'none',\n );\n }\n\n private parseSpec({ spec, id }: { spec: string; id: string }): TaskSpec {\n try {\n return JSON.parse(spec);\n } catch (error) {\n throw new Error(`Failed to parse spec of task '${id}', ${error}`);\n }\n }\n\n private parseTaskSecrets(taskRow: RawDbTaskRow): TaskSecrets | undefined {\n try {\n return taskRow.secrets ? JSON.parse(taskRow.secrets) : undefined;\n } catch (error) {\n throw new Error(\n `Failed to parse secrets of task '${taskRow.id}', ${error}`,\n );\n }\n }\n\n private static async getClient(\n database: DatabaseService | Knex,\n ): Promise<Knex> {\n if (isDatabaseService(database)) {\n return database.getClient();\n }\n\n return database;\n }\n\n private static async runMigrations(\n database: DatabaseService | Knex,\n client: Knex,\n ): Promise<void> {\n if (!isDatabaseService(database)) {\n await client.migrate.latest({\n directory: migrationsDir,\n });\n\n return;\n }\n\n if (!database.migrations?.skip) {\n await client.migrate.latest({\n directory: migrationsDir,\n });\n }\n }\n\n private constructor(client: Knex, events?: EventsService) {\n this.db = client;\n this.events = events;\n }\n\n private getState(task: RawDbTaskRow) {\n try {\n return task.state ? JSON.parse(task.state).state : undefined;\n } catch (error) {\n throw new Error(\n `Failed to parse state of the task '${task.id}', ${error}`,\n );\n }\n }\n\n private isTaskFilter(filter: any): filter is TaskFilter {\n return filter.hasOwnProperty('key');\n }\n\n private parseFilter(\n filter: PermissionCriteria<TaskFilters>,\n query: Knex.QueryBuilder,\n db: Knex,\n negate: boolean = false,\n ): Knex.QueryBuilder {\n if (isNotCriteria(filter)) {\n return this.parseFilter(filter.not, query, db, !negate);\n }\n\n if (this.isTaskFilter(filter)) {\n const values: string[] = compact(filter.values) ?? [];\n if (negate) {\n query.whereNotIn(filter.key, values);\n } else {\n query.whereIn(filter.key, values);\n }\n\n return query;\n }\n\n return query[negate ? 'andWhereNot' : 'andWhere'](subQuery => {\n if (isOrCriteria(filter)) {\n for (const subFilter of filter.anyOf ?? []) {\n subQuery.orWhere(subQueryInner =>\n this.parseFilter(subFilter, subQueryInner, db, false),\n );\n }\n } else if (isAndCriteria(filter)) {\n for (const subFilter of filter.allOf ?? []) {\n subQuery.andWhere(subQueryInner =>\n this.parseFilter(subFilter, subQueryInner, db, false),\n );\n }\n }\n });\n }\n\n async list(options: {\n createdBy?: string;\n status?: TaskStatus;\n filters?: {\n createdBy?: string | string[];\n status?: TaskStatus | TaskStatus[];\n };\n pagination?: {\n limit?: number;\n offset?: number;\n };\n order?: { order: 'asc' | 'desc'; field: string }[];\n permissionFilters?: PermissionCriteria<TaskFilters>;\n }): Promise<{ tasks: SerializedTask[]; totalTasks?: number }> {\n const { createdBy, status, pagination, order, filters, permissionFilters } =\n options ?? {};\n const queryBuilder = this.db<RawDbTaskRow & { count: number }>('tasks');\n\n const createdByValues = flattenParams<string>(\n createdBy,\n filters?.createdBy,\n );\n\n const combinedPermissionFilters:\n | PermissionCriteria<TaskFilters>\n | undefined =\n createdByValues.length > 0\n ? {\n allOf: [\n { key: 'created_by', values: createdByValues },\n ...(permissionFilters ? [permissionFilters] : []),\n ],\n }\n : permissionFilters;\n\n if (combinedPermissionFilters) {\n this.parseFilter(combinedPermissionFilters, queryBuilder, this.db);\n }\n\n if (status || filters?.status) {\n const arr: TaskStatus[] = flattenParams<TaskStatus>(\n status,\n filters?.status,\n );\n queryBuilder.whereIn('status', [...new Set(arr)]);\n }\n\n const countQuery = queryBuilder.clone();\n countQuery.count('tasks.id', { as: 'count' });\n\n if (order) {\n order.forEach(f => {\n queryBuilder.orderBy(f.field, f.order);\n });\n } else {\n queryBuilder.orderBy('created_at', 'desc');\n }\n\n if (pagination?.limit !== undefined) {\n queryBuilder.limit(pagination.limit);\n }\n\n if (pagination?.offset !== undefined) {\n queryBuilder.offset(pagination.offset);\n }\n\n const [results, [{ count }]] = await Promise.all([\n queryBuilder.select(),\n countQuery,\n ]);\n\n const tasks = results.map(result => ({\n id: result.id,\n spec: JSON.parse(result.spec),\n status: result.status,\n createdBy: result.created_by ?? undefined,\n lastHeartbeatAt: parseSqlDateToIsoString(result.last_heartbeat_at),\n createdAt: parseSqlDateToIsoString(result.created_at),\n }));\n\n return { tasks, totalTasks: count };\n }\n\n async getTask(taskId: string): Promise<SerializedTask> {\n const [result] = await this.db<RawDbTaskRow>('tasks')\n .where({ id: taskId })\n .select();\n if (!result) {\n throw new NotFoundError(`No task with id '${taskId}' found`);\n }\n try {\n return this.parseTaskRow(result);\n } catch (error) {\n throw new Error(`Failed to parse spec of task '${taskId}', ${error}`);\n }\n }\n\n private parseTaskRow(result: RawDbTaskRow): SerializedTask {\n const spec = JSON.parse(result.spec);\n const secrets = result.secrets ? JSON.parse(result.secrets) : undefined;\n const state = this.getState(result);\n\n return {\n id: result.id,\n spec,\n status: result.status,\n lastHeartbeatAt: parseSqlDateToIsoString(result.last_heartbeat_at),\n createdAt: parseSqlDateToIsoString(result.created_at),\n createdBy: result.created_by ?? undefined,\n secrets,\n state,\n };\n }\n\n async createTask(\n options: TaskStoreCreateTaskOptions,\n ): Promise<TaskStoreCreateTaskResult> {\n const taskId = uuid();\n await this.db<RawDbTaskRow>('tasks').insert({\n id: taskId,\n spec: JSON.stringify(options.spec),\n secrets: options.secrets ? JSON.stringify(options.secrets) : undefined,\n created_by: options.createdBy ?? null,\n status: 'open',\n });\n\n this.events?.publish({\n topic: 'scaffolder.task',\n eventPayload: {\n id: taskId,\n spec: options.spec,\n createdBy: options.createdBy,\n status: 'open',\n },\n });\n\n return { taskId };\n }\n\n async claimTask(): Promise<SerializedTask | undefined> {\n return this.db.transaction(async tx => {\n const [task] = await tx<RawDbTaskRow>('tasks')\n .where({\n status: 'open',\n })\n .limit(1)\n .select();\n\n if (!task) {\n return undefined;\n }\n\n const spec = this.parseSpec(task);\n\n const updateCount = await tx<RawDbTaskRow>('tasks')\n .where({ id: task.id, status: 'open' })\n .update({\n status: 'processing',\n last_heartbeat_at: this.db.fn.now(),\n // remove the secrets for non-recoverable tasks when moving to processing state.\n secrets: this.isRecoverableTask(spec) ? task.secrets : null,\n });\n\n if (updateCount < 1) {\n return undefined;\n }\n\n const ret: SerializedTask = {\n id: task.id,\n spec,\n status: 'processing',\n lastHeartbeatAt: task.last_heartbeat_at,\n createdAt: task.created_at,\n createdBy: task.created_by ?? undefined,\n state: this.getState(task),\n };\n\n this.events?.publish({\n topic: 'scaffolder.task',\n eventPayload: ret,\n });\n\n const secrets = this.parseTaskSecrets(task);\n return { ...ret, secrets };\n });\n }\n\n async heartbeatTask(taskId: string): Promise<void> {\n const updateCount = await this.db<RawDbTaskRow>('tasks')\n .where({ id: taskId, status: 'processing' })\n .update({\n last_heartbeat_at: this.db.fn.now(),\n });\n if (updateCount === 0) {\n throw new ConflictError(`No running task with taskId ${taskId} found`);\n }\n }\n\n async listStaleTasks(options: { timeoutS: number }): Promise<{\n tasks: { taskId: string; recovery?: TaskRecovery }[];\n }> {\n const { timeoutS } = options;\n const heartbeatInterval = intervalFromNowTill(timeoutS, this.db);\n const rawRows = await this.db<RawDbTaskRow>('tasks')\n .where('status', 'processing')\n .andWhere('last_heartbeat_at', '<=', heartbeatInterval);\n const tasks = rawRows.map(row => ({\n recovery: (JSON.parse(row.spec) as TaskSpec).EXPERIMENTAL_recovery,\n taskId: row.id,\n }));\n return { tasks };\n }\n\n async completeTask(options: {\n taskId: string;\n status: TaskStatus;\n eventBody: JsonObject;\n }): Promise<void> {\n const { taskId, status, eventBody } = options;\n\n let oldStatus: TaskStatus;\n if (['failed', 'completed', 'cancelled'].includes(status)) {\n oldStatus = 'processing';\n } else {\n throw new Error(\n `Invalid status update of run '${taskId}' to status '${status}'`,\n );\n }\n\n await this.db.transaction(async tx => {\n const [task] = await tx<RawDbTaskRow>('tasks')\n .where({\n id: taskId,\n })\n .limit(1)\n .select();\n\n const updateTask = async (criteria: {\n id: string;\n status?: TaskStatus;\n }) => {\n const updateCount = await tx<RawDbTaskRow>('tasks')\n .where(criteria)\n .update({\n status,\n secrets: null,\n });\n\n if (updateCount !== 1) {\n throw new ConflictError(\n `Failed to update status to '${status}' for taskId ${taskId}`,\n );\n }\n\n this.events?.publish({\n topic: 'scaffolder.task',\n eventPayload: {\n id: taskId,\n status: status,\n lastHeartbeatAt: task.last_heartbeat_at,\n createdAt: task.created_at,\n createdBy: task.created_by,\n state: this.getState(task),\n },\n });\n\n await tx<RawDbTaskEventRow>('task_events')\n .insert({\n task_id: taskId,\n event_type: 'completion',\n body: JSON.stringify(eventBody),\n })\n .returning('id');\n };\n\n if (status === 'cancelled') {\n await updateTask({\n id: taskId,\n });\n return;\n }\n\n if (task.status === 'cancelled') {\n return;\n }\n\n if (!task) {\n throw new Error(`No task with taskId ${taskId} found`);\n }\n if (task.status !== oldStatus) {\n throw new ConflictError(\n `Refusing to update status of run '${taskId}' to status '${status}' ` +\n `as it is currently '${task.status}', expected '${oldStatus}'`,\n );\n }\n\n await updateTask({\n id: taskId,\n status: oldStatus,\n });\n });\n }\n\n async emitLogEvent(\n options: TaskStoreEmitOptions<{ message: string } & JsonObject>,\n ): Promise<void> {\n const { taskId, body } = options;\n const serializedBody = JSON.stringify(body);\n await this.db<RawDbTaskEventRow>('task_events')\n .insert({\n task_id: taskId,\n event_type: 'log',\n body: serializedBody,\n })\n .returning('id');\n }\n\n async getTaskState({ taskId }: { taskId: string }): Promise<\n | {\n state: JsonObject;\n }\n | undefined\n > {\n const [result] = await this.db<RawDbTaskRow>('tasks')\n .where({ id: taskId })\n .select('state');\n return result.state ? JSON.parse(result.state) : undefined;\n }\n\n async saveTaskState(options: {\n taskId: string;\n state?: JsonObject;\n }): Promise<void> {\n if (options.state) {\n const serializedState = JSON.stringify({ state: options.state });\n await this.db<RawDbTaskRow>('tasks')\n .where({ id: options.taskId })\n .update({\n state: serializedState,\n });\n }\n }\n\n async listEvents(\n options: TaskStoreListEventsOptions,\n ): Promise<{ events: SerializedTaskEvent[] }> {\n const { isTaskRecoverable, taskId, after } = options;\n const rawEvents = await this.db<RawDbTaskEventRow>('task_events')\n .where({\n task_id: taskId,\n })\n .andWhere(builder => {\n if (typeof after === 'number') {\n builder.where('id', '>', after).orWhere('event_type', 'completion');\n }\n })\n .orderBy('id')\n .select();\n\n const events = rawEvents.map(event => {\n try {\n const body = JSON.parse(event.body) as SerializedTaskEvent['body'];\n return {\n id: Number(event.id),\n isTaskRecoverable,\n taskId,\n body,\n type: event.event_type,\n createdAt: parseSqlDateToIsoString(event.created_at),\n };\n } catch (error) {\n throw new Error(\n `Failed to parse event body from event taskId=${taskId} id=${event.id}, ${error}`,\n );\n }\n });\n\n return trimEventsTillLastRecovery(events);\n }\n\n async shutdownTask(options: TaskStoreShutDownTaskOptions): Promise<void> {\n const { taskId } = options;\n const message = `This task was marked as stale as it exceeded its timeout`;\n\n const statusStepEvents = (await this.listEvents({ taskId })).events.filter(\n ({ body }) => body?.stepId,\n );\n\n const completedSteps = statusStepEvents\n .filter(\n ({ body: { status } }) => status === 'failed' || status === 'completed',\n )\n .map(step => step.body.stepId);\n\n const hungProcessingSteps = statusStepEvents\n .filter(({ body: { status } }) => status === 'processing')\n .map(event => event.body.stepId)\n .filter(step => !completedSteps.includes(step));\n\n for (const step of hungProcessingSteps) {\n await this.emitLogEvent({\n taskId,\n body: {\n message,\n stepId: step,\n status: 'failed',\n },\n });\n }\n\n await this.completeTask({\n taskId,\n status: 'failed',\n eventBody: {\n message,\n },\n });\n }\n\n async rehydrateWorkspace(options: {\n taskId: string;\n targetPath: string;\n }): Promise<void> {\n const [result] = await this.db<RawDbTaskRow>('tasks')\n .where({ id: options.taskId })\n .select('workspace');\n\n await restoreWorkspace({\n path: options.targetPath,\n buffer: result.workspace,\n });\n }\n\n async cleanWorkspace({ taskId }: { taskId: string }): Promise<void> {\n await this.db('tasks').where({ id: taskId }).update({\n workspace: null,\n });\n }\n\n async serializeWorkspace(options: {\n path: string;\n taskId: string;\n }): Promise<void> {\n if (options.path) {\n const workspace = (await serializeWorkspace(options)).contents;\n await this.db<RawDbTaskRow>('tasks')\n .where({ id: options.taskId })\n .update({\n workspace,\n });\n }\n }\n\n async cancelTask(\n options: TaskStoreEmitOptions<{ message: string } & JsonObject>,\n ): Promise<void> {\n const { taskId, body } = options;\n const serializedBody = JSON.stringify(body);\n const [ret] = await this.db<RawDbTaskEventRow>('task_events')\n .insert({\n task_id: taskId,\n event_type: 'cancelled',\n body: serializedBody,\n })\n .returning('id');\n\n this.events?.publish({\n topic: 'scaffolder.task',\n eventPayload: {\n id: ret.id,\n taskId,\n status: 'cancelled',\n body,\n },\n });\n }\n\n async retryTask(options: {\n secrets?: TaskSecrets;\n taskId: string;\n }): Promise<void> {\n const { secrets, taskId } = options;\n\n await this.db.transaction(async tx => {\n const result = await tx<RawDbTaskRow>('tasks')\n .where('id', taskId)\n .update(\n {\n ...(secrets && { secrets: JSON.stringify(secrets) }),\n status: 'open',\n last_heartbeat_at: this.db.fn.now(),\n },\n ['id', 'spec'],\n );\n\n for (const { id, spec } of result) {\n const taskSpec = JSON.parse(spec as string) as TaskSpec;\n\n /**\n * Once task is picked up, all event types are replayed.\n * We have to remove cancelled or completion event_type as these are as actions for frontend to perform.\n * In contrary, we send 'recovered' event_type to reset the state on the frontend side.\n *\n */\n await tx<RawDbTaskEventRow>('task_events')\n .where('task_id', id)\n .andWhere(q => q.whereIn('event_type', ['cancelled', 'completion']))\n .del();\n\n await tx<RawDbTaskEventRow>('task_events').insert({\n task_id: id,\n event_type: 'recovered',\n body: JSON.stringify({\n recoverStrategy:\n taskSpec.EXPERIMENTAL_recovery?.EXPERIMENTAL_strategy ?? 'none',\n }),\n });\n }\n });\n }\n\n async recoverTasks(\n options: TaskStoreRecoverTaskOptions,\n ): Promise<{ ids: string[] }> {\n const taskIdsToRecover: string[] = [];\n const timeoutS = Duration.fromObject(options.timeout).as('seconds');\n\n await this.db.transaction(async tx => {\n const heartbeatInterval = intervalFromNowTill(timeoutS, this.db);\n\n const result = await tx<RawDbTaskRow>('tasks')\n .where('status', 'processing')\n .andWhere('last_heartbeat_at', '<=', heartbeatInterval)\n .update(\n {\n status: 'open',\n last_heartbeat_at: this.db.fn.now(),\n },\n ['id', 'spec'],\n );\n\n taskIdsToRecover.push(...result.map(i => i.id));\n\n for (const { id, spec } of result) {\n const taskSpec = JSON.parse(spec as string) as TaskSpec;\n const event = {\n recoverStrategy:\n taskSpec.EXPERIMENTAL_recovery?.EXPERIMENTAL_strategy ?? 'none',\n };\n const [ret] = await tx<RawDbTaskEventRow>('task_events')\n .insert({\n task_id: id,\n event_type: 'recovered',\n body: JSON.stringify(event),\n })\n .returning('id');\n\n this.events?.publish({\n topic: 'scaffolder.task',\n eventPayload: {\n id: ret.id,\n taskId: id,\n status: 'recovered',\n body: event,\n },\n });\n }\n });\n\n return { ids: taskIdsToRecover };\n }\n}\n"],"names":["resolvePackagePath","DateTime","isNotCriteria","compact","isOrCriteria","isAndCriteria","flattenParams","NotFoundError","uuid","ConflictError","intervalFromNowTill","trimEventsTillLastRecovery","restoreWorkspace","serializeWorkspace","Duration"],"mappings":"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"}
|
|
@@ -434,12 +434,24 @@ class NunjucksWorkflowRunner {
|
|
|
434
434
|
const workspacePath = path__default.default.join(this.options.workingDirectory, taskId);
|
|
435
435
|
const { additionalTemplateFilters, additionalTemplateGlobals } = this.options;
|
|
436
436
|
this.environment = await this.getEnvironmentConfig();
|
|
437
|
+
const taskState = { failed: false };
|
|
438
|
+
const statusCheckInvoked = { value: false };
|
|
437
439
|
const renderTemplate = await SecureTemplater.SecureTemplater.loadRenderer({
|
|
438
440
|
templateFilters: {
|
|
439
441
|
...this.defaultTemplateFilters,
|
|
440
442
|
...additionalTemplateFilters
|
|
441
443
|
},
|
|
442
|
-
templateGlobals:
|
|
444
|
+
templateGlobals: {
|
|
445
|
+
...additionalTemplateGlobals,
|
|
446
|
+
always: () => {
|
|
447
|
+
statusCheckInvoked.value = true;
|
|
448
|
+
return true;
|
|
449
|
+
},
|
|
450
|
+
failure: () => {
|
|
451
|
+
statusCheckInvoked.value = true;
|
|
452
|
+
return taskState.failed;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
443
455
|
});
|
|
444
456
|
try {
|
|
445
457
|
await task.rehydrateWorkspace?.({ taskId, targetPath: workspacePath });
|
|
@@ -463,16 +475,64 @@ class NunjucksWorkflowRunner {
|
|
|
463
475
|
[{ permission: alpha.actionExecutePermission }],
|
|
464
476
|
{ credentials: await task.getInitiatorCredentials() }
|
|
465
477
|
) : [{ result: pluginPermissionCommon.AuthorizeResult.ALLOW }];
|
|
478
|
+
let firstError;
|
|
479
|
+
const allErrors = [];
|
|
466
480
|
for (const step of task.spec.steps) {
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
481
|
+
if (taskState.failed) {
|
|
482
|
+
if (typeof step.if !== "string") {
|
|
483
|
+
await task.emitLog(
|
|
484
|
+
`Skipping step ${step.id} because a previous step failed`,
|
|
485
|
+
{ stepId: step.id, status: "skipped" }
|
|
486
|
+
);
|
|
487
|
+
continue;
|
|
488
|
+
}
|
|
489
|
+
statusCheckInvoked.value = false;
|
|
490
|
+
this.render(step.if, context, renderTemplate);
|
|
491
|
+
if (!statusCheckInvoked.value) {
|
|
492
|
+
await task.emitLog(
|
|
493
|
+
`Skipping step ${step.id} because a previous step failed`,
|
|
494
|
+
{ stepId: step.id, status: "skipped" }
|
|
495
|
+
);
|
|
496
|
+
continue;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
try {
|
|
500
|
+
await this.executeStep(
|
|
501
|
+
task,
|
|
502
|
+
step,
|
|
503
|
+
context,
|
|
504
|
+
renderTemplate,
|
|
505
|
+
taskTrack,
|
|
506
|
+
workspacePath,
|
|
507
|
+
decision
|
|
508
|
+
);
|
|
509
|
+
} catch (err) {
|
|
510
|
+
const error = err;
|
|
511
|
+
allErrors.push({ step, error });
|
|
512
|
+
if (!firstError) {
|
|
513
|
+
firstError = error;
|
|
514
|
+
} else {
|
|
515
|
+
this.options.logger.error(
|
|
516
|
+
`Additional error in step ${step.id} (${step.name}): ${error.message}`,
|
|
517
|
+
error
|
|
518
|
+
);
|
|
519
|
+
await task.emitLog(
|
|
520
|
+
`Additional error occurred: ${error.message}
|
|
521
|
+
${error.stack}`,
|
|
522
|
+
{ stepId: step.id, status: "failed" }
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
taskState.failed = true;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
if (firstError) {
|
|
529
|
+
if (allErrors.length > 1) {
|
|
530
|
+
const additionalErrorSummary = allErrors.slice(1).map(({ step }) => `${step.id} (${step.name})`).join(", ");
|
|
531
|
+
this.options.logger.warn(
|
|
532
|
+
`Task failed with ${allErrors.length} errors. First error from step ${allErrors[0].step.id}. Additional failures in: ${additionalErrorSummary}`
|
|
533
|
+
);
|
|
534
|
+
}
|
|
535
|
+
throw firstError;
|
|
476
536
|
}
|
|
477
537
|
const output = this.render(task.spec.output, context, renderTemplate);
|
|
478
538
|
if (Array.isArray(output?.links)) {
|
|
@@ -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 nunjucks from 'nunjucks';\nimport path from 'node:path';\nimport * as winston from 'winston';\nimport {\n SecureTemplater,\n SecureTemplateRenderer,\n} from '../../lib/templating/SecureTemplater';\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 {\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 TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport { createDefaultFilters } from '../../lib/templating/filters/createDefaultFilters';\nimport { scaffolderActionRules } from '../../service/rules';\nimport { createCounterMetric, createHistogramMetric } from '../../util/metrics';\nimport { BackstageLoggerTransport, WinstonLogger } from './logger';\nimport { convertFiltersToRecord } from '../../util/templating';\nimport {\n CheckpointContext,\n CheckpointState,\n} from '@backstage/plugin-scaffolder-node/alpha';\nimport { Config } from '@backstage/config';\nimport { resolveDefaultEnvironment } from '../../lib/defaultEnvironment';\n\ntype NunjucksWorkflowRunnerOptions = {\n workingDirectory: string;\n actionRegistry: TemplateActionRegistry;\n integrations: ScmIntegrations;\n logger: LoggerService;\n auditor?: AuditorService;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n additionalTemplateGlobals?: Record<string, TemplateGlobal>;\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\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 defaultTemplateFilters: Record<string, TemplateFilter>;\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.defaultTemplateFilters = convertFiltersToRecord(\n createDefaultFilters({\n integrations: this.options.integrations,\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 isSingleTemplateString(input: string) {\n const { parser, nodes } = nunjucks as unknown as {\n parser: {\n parse(\n template: string,\n ctx: object,\n options: nunjucks.ConfigureOptions,\n ): { children: { children?: unknown[] }[] };\n };\n nodes: { TemplateData: Function };\n };\n\n const parsed = parser.parse(\n input,\n {},\n {\n autoescape: false,\n tags: {\n variableStart: '${{',\n variableEnd: '}}',\n },\n },\n );\n\n return (\n parsed.children.length === 1 &&\n !(parsed.children[0]?.children?.[0] instanceof nodes.TemplateData)\n );\n }\n\n private render<T>(\n input: T,\n context: TemplateContext,\n renderTemplate: SecureTemplateRenderer,\n ): T {\n return JSON.parse(JSON.stringify(input), (_key, value) => {\n try {\n if (typeof value === 'string') {\n try {\n if (this.isSingleTemplateString(value)) {\n // Lets convert ${{ parameters.bob }} to ${{ (parameters.bob) | dump }} so we can keep the input type\n const wrappedDumped = value.replace(\n /\\${{(.+)}}/g,\n '${{ ( $1 ) | dump }}',\n );\n\n // Run the templating\n const templated = renderTemplate(wrappedDumped, context);\n\n // If there's an empty string returned, then it's undefined\n if (templated === '') {\n return undefined;\n }\n\n // Reparse the dumped string\n return JSON.parse(templated);\n }\n } catch (ex) {\n this.options.logger.error(\n `Failed to parse template string: ${value} with error ${ex.message}`,\n );\n }\n\n // Fallback to default behaviour\n const templated = renderTemplate(value, context);\n\n if (templated === '') {\n return undefined;\n }\n\n return templated;\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 renderTemplate: (template: string, values: unknown) => string,\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, context, renderTemplate)))\n ) {\n await stepTrack.skipFalsy();\n return;\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 debugInput =\n (step.input &&\n this.render(\n step.input,\n {\n ...context,\n environment: {\n parameters: this.environment?.parameters || {},\n secrets: redactedEnvironmentSecrets,\n },\n secrets: redactedSecrets,\n },\n renderTemplate,\n )) ??\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;\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.isDryRun ? {} : task.secrets ?? {},\n };\n\n const resolvedEach =\n step.each &&\n this.render(step.each, preIterationContext, renderTemplate);\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 fullContext = { ...preIterationContext, ...i };\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, fullContext, renderTemplate));\n\n return {\n ...i,\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, fullContext, renderTemplate)\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 (k, v) => (k ? String(v) : v),\n 0,\n )}`,\n );\n continue;\n }\n taskLogger.info(\n `Running step each: ${JSON.stringify(\n iteration.each,\n (k, v) => (k ? String(v) : v),\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 contextNoSecrets = {\n ...preIterationContext,\n ...(iteration.each ? { each: iteration.each } : {}),\n secrets: {},\n environment: {\n ...preIterationContext.environment,\n secrets: {},\n },\n };\n const inputWithoutSecrets = this.render(\n step.input,\n contextNoSecrets,\n renderTemplate,\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\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 const value = prevValue ? prevValue : await fn();\n\n if (!prevValue) {\n task.updateCheckpoint?.({\n key,\n status: 'success',\n value: value ?? {},\n });\n }\n return value;\n } catch (err) {\n task.updateCheckpoint?.({\n key,\n status: 'failed',\n reason: stringifyError(err),\n });\n throw err;\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\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 } 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 { additionalTemplateFilters, additionalTemplateGlobals } =\n this.options;\n\n this.environment = await this.getEnvironmentConfig();\n\n const renderTemplate = await SecureTemplater.loadRenderer({\n templateFilters: {\n ...this.defaultTemplateFilters,\n ...additionalTemplateFilters,\n },\n templateGlobals: additionalTemplateGlobals,\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\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 for (const step of task.spec.steps) {\n await this.executeStep(\n task,\n step,\n context,\n renderTemplate,\n taskTrack,\n workspacePath,\n decision,\n );\n }\n\n const output = this.render(task.spec.output, context, renderTemplate);\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 promtStepCount = 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 promtStepCount.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 promtStepCount.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 promtStepCount.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","convertFiltersToRecord","createDefaultFilters","defaultEnvironment","resolveDefaultEnvironment","nunjucks","templated","isTruthy","generateExampleOutput","InputError","validateJsonSchema","errors","NotAllowedError","stringifyError","fs","path","SecureTemplater","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 nunjucks from 'nunjucks';\nimport path from 'node:path';\nimport * as winston from 'winston';\nimport {\n SecureTemplater,\n SecureTemplateRenderer,\n} from '../../lib/templating/SecureTemplater';\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 {\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 TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport { createDefaultFilters } from '../../lib/templating/filters/createDefaultFilters';\nimport { scaffolderActionRules } from '../../service/rules';\nimport { createCounterMetric, createHistogramMetric } from '../../util/metrics';\nimport { BackstageLoggerTransport, WinstonLogger } from './logger';\nimport { convertFiltersToRecord } from '../../util/templating';\nimport {\n CheckpointContext,\n CheckpointState,\n} from '@backstage/plugin-scaffolder-node/alpha';\nimport { Config } from '@backstage/config';\nimport { resolveDefaultEnvironment } from '../../lib/defaultEnvironment';\n\ntype NunjucksWorkflowRunnerOptions = {\n workingDirectory: string;\n actionRegistry: TemplateActionRegistry;\n integrations: ScmIntegrations;\n logger: LoggerService;\n auditor?: AuditorService;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n additionalTemplateGlobals?: Record<string, TemplateGlobal>;\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\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 defaultTemplateFilters: Record<string, TemplateFilter>;\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.defaultTemplateFilters = convertFiltersToRecord(\n createDefaultFilters({\n integrations: this.options.integrations,\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 isSingleTemplateString(input: string) {\n const { parser, nodes } = nunjucks as unknown as {\n parser: {\n parse(\n template: string,\n ctx: object,\n options: nunjucks.ConfigureOptions,\n ): { children: { children?: unknown[] }[] };\n };\n nodes: { TemplateData: Function };\n };\n\n const parsed = parser.parse(\n input,\n {},\n {\n autoescape: false,\n tags: {\n variableStart: '${{',\n variableEnd: '}}',\n },\n },\n );\n\n return (\n parsed.children.length === 1 &&\n !(parsed.children[0]?.children?.[0] instanceof nodes.TemplateData)\n );\n }\n\n private render<T>(\n input: T,\n context: TemplateContext,\n renderTemplate: SecureTemplateRenderer,\n ): T {\n return JSON.parse(JSON.stringify(input), (_key, value) => {\n try {\n if (typeof value === 'string') {\n try {\n if (this.isSingleTemplateString(value)) {\n // Lets convert ${{ parameters.bob }} to ${{ (parameters.bob) | dump }} so we can keep the input type\n const wrappedDumped = value.replace(\n /\\${{(.+)}}/g,\n '${{ ( $1 ) | dump }}',\n );\n\n // Run the templating\n const templated = renderTemplate(wrappedDumped, context);\n\n // If there's an empty string returned, then it's undefined\n if (templated === '') {\n return undefined;\n }\n\n // Reparse the dumped string\n return JSON.parse(templated);\n }\n } catch (ex) {\n this.options.logger.error(\n `Failed to parse template string: ${value} with error ${ex.message}`,\n );\n }\n\n // Fallback to default behaviour\n const templated = renderTemplate(value, context);\n\n if (templated === '') {\n return undefined;\n }\n\n return templated;\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 renderTemplate: (template: string, values: unknown) => string,\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, context, renderTemplate)))\n ) {\n await stepTrack.skipFalsy();\n return;\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 debugInput =\n (step.input &&\n this.render(\n step.input,\n {\n ...context,\n environment: {\n parameters: this.environment?.parameters || {},\n secrets: redactedEnvironmentSecrets,\n },\n secrets: redactedSecrets,\n },\n renderTemplate,\n )) ??\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;\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.isDryRun ? {} : task.secrets ?? {},\n };\n\n const resolvedEach =\n step.each &&\n this.render(step.each, preIterationContext, renderTemplate);\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 fullContext = { ...preIterationContext, ...i };\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, fullContext, renderTemplate));\n\n return {\n ...i,\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, fullContext, renderTemplate)\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 (k, v) => (k ? String(v) : v),\n 0,\n )}`,\n );\n continue;\n }\n taskLogger.info(\n `Running step each: ${JSON.stringify(\n iteration.each,\n (k, v) => (k ? String(v) : v),\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 contextNoSecrets = {\n ...preIterationContext,\n ...(iteration.each ? { each: iteration.each } : {}),\n secrets: {},\n environment: {\n ...preIterationContext.environment,\n secrets: {},\n },\n };\n const inputWithoutSecrets = this.render(\n step.input,\n contextNoSecrets,\n renderTemplate,\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\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 const value = prevValue ? prevValue : await fn();\n\n if (!prevValue) {\n task.updateCheckpoint?.({\n key,\n status: 'success',\n value: value ?? {},\n });\n }\n return value;\n } catch (err) {\n task.updateCheckpoint?.({\n key,\n status: 'failed',\n reason: stringifyError(err),\n });\n throw err;\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\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 } 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 { additionalTemplateFilters, additionalTemplateGlobals } =\n 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 renderTemplate = await SecureTemplater.loadRenderer({\n templateFilters: {\n ...this.defaultTemplateFilters,\n ...additionalTemplateFilters,\n },\n templateGlobals: {\n ...additionalTemplateGlobals,\n always: () => {\n statusCheckInvoked.value = true;\n return true;\n },\n failure: () => {\n statusCheckInvoked.value = true;\n return taskState.failed;\n },\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\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, context, renderTemplate);\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 await this.executeStep(\n task,\n step,\n context,\n renderTemplate,\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(task.spec.output, context, renderTemplate);\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 promtStepCount = 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 promtStepCount.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 promtStepCount.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 promtStepCount.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","convertFiltersToRecord","createDefaultFilters","defaultEnvironment","resolveDefaultEnvironment","nunjucks","templated","isTruthy","generateExampleOutput","InputError","validateJsonSchema","errors","NotAllowedError","stringifyError","fs","path","SecureTemplater","actionExecutePermission","AuthorizeResult","filterConditionalItems","metrics","createCounterMetric","createHistogramMetric"],"mappings":"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"}
|
|
@@ -13,7 +13,7 @@ var alpha$1 = require('@backstage/plugin-scaffolder-node/alpha');
|
|
|
13
13
|
var express = require('express');
|
|
14
14
|
var luxon = require('luxon');
|
|
15
15
|
var node_url = require('node:url');
|
|
16
|
-
var
|
|
16
|
+
var node_crypto = require('node:crypto');
|
|
17
17
|
var v3 = require('zod/v3');
|
|
18
18
|
require('@backstage/plugin-scaffolder-node');
|
|
19
19
|
require('../scaffolder/actions/builtin/catalog/register.examples.cjs.js');
|
|
@@ -780,7 +780,7 @@ data: ${JSON.stringify(event)}
|
|
|
780
780
|
id: step.id ?? `step-${index + 1}`,
|
|
781
781
|
name: step.name ?? step.action
|
|
782
782
|
}));
|
|
783
|
-
const dryRunId =
|
|
783
|
+
const dryRunId = node_crypto.randomUUID();
|
|
784
784
|
const contentsPath = backendPluginApi.resolveSafeChildPath(
|
|
785
785
|
workingDirectory,
|
|
786
786
|
`dry-run-content-${dryRunId}`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.cjs.js","sources":["../../src/service/router.ts"],"sourcesContent":["/*\n * Copyright 2020 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 {\n AuditorService,\n AuditorServiceEvent,\n AuthService,\n BackstageCredentials,\n DatabaseService,\n HttpAuthService,\n LifecycleService,\n LoggerService,\n PermissionsRegistryService,\n PermissionsService,\n resolveSafeChildPath,\n SchedulerService,\n} from '@backstage/backend-plugin-api';\nimport { validate, ValidatorResult } from 'jsonschema';\nimport {\n CompoundEntityRef,\n Entity,\n parseEntityRef,\n stringifyEntityRef,\n UserEntity,\n} from '@backstage/catalog-model';\nimport { Config, readDurationFromConfig } from '@backstage/config';\nimport { InputError, NotFoundError } from '@backstage/errors';\nimport { ScmIntegrations } from '@backstage/integration';\n\nimport { EventsService } from '@backstage/plugin-events-node';\n\nimport {\n ConditionTransformer,\n createConditionAuthorizer,\n createConditionTransformer,\n} from '@backstage/plugin-permission-node';\nimport {\n TaskSpec,\n TemplateEntityV1beta3,\n templateEntityV1beta3Validator,\n} from '@backstage/plugin-scaffolder-common';\nimport {\n scaffolderActionPermissions,\n scaffolderTaskPermissions,\n scaffolderTemplatePermissions,\n taskCancelPermission,\n taskCreatePermission,\n taskReadPermission,\n templateManagementPermission,\n templateParameterReadPermission,\n templateStepReadPermission,\n} from '@backstage/plugin-scaffolder-common/alpha';\nimport {\n TaskBroker,\n TaskFilters,\n TaskStatus,\n TemplateAction,\n TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport {\n AutocompleteHandler,\n CreatedTemplateFilter,\n CreatedTemplateGlobal,\n scaffolderActionPermissionResourceRef,\n scaffolderTaskPermissionResourceRef,\n scaffolderTemplatePermissionResourceRef,\n WorkspaceProvider,\n} from '@backstage/plugin-scaffolder-node/alpha';\nimport { HumanDuration, JsonObject } from '@backstage/types';\nimport express from 'express';\nimport { Duration } from 'luxon';\nimport { pathToFileURL } from 'node:url';\nimport { v4 as uuid } from 'uuid';\nimport { z } from 'zod/v3';\nimport {\n DatabaseTaskStore,\n DefaultTemplateActionRegistry,\n TaskWorker,\n} from '../scaffolder';\nimport { createDryRunner } from '../scaffolder/dryrun';\nimport { StorageTaskBroker } from '../scaffolder/tasks/StorageTaskBroker';\nimport { InternalTaskSecrets } from '../scaffolder/tasks/types';\nimport { createOpenApiRouter } from '../schema/openapi';\nimport {\n checkPermission,\n checkTaskPermission,\n getAuthorizeConditions,\n} from '../util/checkPermissions';\nimport {\n findTemplate,\n getEntityBaseUrl,\n getWorkingDirectory,\n parseStringsParam,\n} from './helpers';\n\nimport {\n convertFiltersToRecord,\n convertGlobalsToRecord,\n extractFilterMetadata,\n extractGlobalFunctionMetadata,\n extractGlobalValueMetadata,\n} from '../util/templating';\nimport { createDefaultFilters } from '../lib/templating/filters/createDefaultFilters';\nimport {\n ActionPermissionRuleInput,\n isActionPermissionRuleInput,\n isTaskPermissionRuleInput,\n isTemplatePermissionRuleInput,\n ScaffolderPermissionRuleInput,\n TaskPermissionRuleInput,\n TemplatePermissionRuleInput,\n} from './permissions';\nimport { CatalogService } from '@backstage/plugin-catalog-node';\n\nimport {\n scaffolderActionRules,\n scaffolderTaskRules,\n scaffolderTemplateRules,\n} from './rules';\nimport {\n ActionsService,\n MetricsService,\n} from '@backstage/backend-plugin-api/alpha';\n\n/**\n * RouterOptions\n */\nexport interface RouterOptions {\n logger: LoggerService;\n config: Config;\n lifecycle?: LifecycleService;\n database: DatabaseService;\n catalog: CatalogService;\n scheduler?: SchedulerService;\n actions?: TemplateAction<any, any, any>[];\n /**\n * Sets the number of concurrent tasks that can be run at any given time on the TaskWorker\n * @defaultValue 10\n */\n concurrentTasksLimit?: number;\n taskBroker?: TaskBroker;\n additionalTemplateFilters?:\n | Record<string, TemplateFilter>\n | CreatedTemplateFilter<any, any>[];\n additionalTemplateGlobals?:\n | Record<string, TemplateGlobal>\n | CreatedTemplateGlobal[];\n additionalWorkspaceProviders?: Record<string, WorkspaceProvider>;\n permissions?: PermissionsService;\n permissionsRegistry: PermissionsRegistryService;\n permissionRules?: Array<ScaffolderPermissionRuleInput>;\n auth: AuthService;\n httpAuth: HttpAuthService;\n events?: EventsService;\n auditor?: AuditorService;\n autocompleteHandlers?: Record<string, AutocompleteHandler>;\n actionsRegistry: ActionsService;\n metrics: MetricsService;\n}\n\nfunction isSupportedTemplate(entity: TemplateEntityV1beta3) {\n return entity.apiVersion === 'scaffolder.backstage.io/v1beta3';\n}\n\nconst readDuration = (\n config: Config,\n key: string,\n defaultValue: HumanDuration,\n) => {\n if (config.has(key)) {\n return readDurationFromConfig(config, { key });\n }\n return defaultValue;\n};\n\nfunction formatSecretsValidationErrors(result: ValidatorResult) {\n return result.errors.map(err => {\n const property = err.property.replace(/^instance/, 'secrets');\n const secretName = err.argument;\n const message =\n err.name === 'required'\n ? `secrets.${secretName} is required`\n : `${property} ${err.message}`;\n return {\n ...err,\n property,\n message,\n instance: {},\n };\n });\n}\n\nasync function validateSecrets(options: {\n template: TemplateEntityV1beta3;\n secrets: Record<string, unknown>;\n res: express.Response;\n auditorEvent?: AuditorServiceEvent;\n}): Promise<boolean> {\n const { template, secrets, res, auditorEvent } = options;\n if (!template.spec.secrets?.schema) {\n return true;\n }\n\n const result = validate(secrets, template.spec.secrets.schema);\n if (result.valid) {\n return true;\n }\n\n await auditorEvent?.fail({\n error: new InputError('Secrets validation failed'),\n });\n\n res.status(400).json({\n errors: formatSecretsValidationErrors(result),\n });\n return false;\n}\n\n/**\n * A method to create a router for the scaffolder backend plugin.\n */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const router = await createOpenApiRouter({\n middleware: [\n // Be generous in upload size to support a wide range of templates in dry-run mode.\n express.json({ limit: '10MB' }),\n ],\n });\n\n const {\n logger: parentLogger,\n config,\n database,\n catalog,\n actions = [],\n scheduler,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n additionalWorkspaceProviders,\n permissions,\n permissionsRegistry,\n permissionRules,\n autocompleteHandlers = {},\n events: eventsService,\n auth,\n httpAuth,\n auditor,\n actionsRegistry,\n metrics,\n } = options;\n\n const concurrentTasksLimit =\n options.concurrentTasksLimit ??\n options.config.getOptionalNumber('scaffolder.concurrentTasksLimit');\n\n const logger = parentLogger.child({ plugin: 'scaffolder' });\n\n const workingDirectory = await getWorkingDirectory(config, logger);\n const integrations = ScmIntegrations.fromConfig(config);\n\n let taskBroker: TaskBroker;\n if (!options.taskBroker) {\n const databaseTaskStore = await DatabaseTaskStore.create({\n database,\n events: eventsService,\n });\n taskBroker = new StorageTaskBroker(\n databaseTaskStore,\n logger,\n config,\n auth,\n additionalWorkspaceProviders,\n auditor,\n );\n\n if (scheduler && databaseTaskStore.listStaleTasks) {\n await scheduler.scheduleTask({\n id: 'close_stale_tasks',\n frequency: readDuration(\n config,\n 'scaffolder.taskTimeoutJanitorFrequency',\n {\n minutes: 5,\n },\n ),\n timeout: { minutes: 15 },\n fn: async () => {\n const { tasks } = await databaseTaskStore.listStaleTasks({\n timeoutS: Duration.fromObject(\n readDuration(config, 'scaffolder.taskTimeout', {\n hours: 24,\n }),\n ).as('seconds'),\n });\n\n for (const task of tasks) {\n await databaseTaskStore.shutdownTask(task);\n logger.info(`Successfully closed stale task ${task.taskId}`);\n }\n },\n });\n }\n } else {\n taskBroker = options.taskBroker;\n }\n\n const actionRegistry = new DefaultTemplateActionRegistry(\n actionsRegistry,\n logger,\n );\n\n const templateExtensions = {\n additionalTemplateFilters: convertFiltersToRecord(\n additionalTemplateFilters,\n ),\n additionalTemplateGlobals: convertGlobalsToRecord(\n additionalTemplateGlobals,\n ),\n };\n\n const workers: TaskWorker[] = [];\n if (concurrentTasksLimit !== 0) {\n const gracefulShutdown = config.getOptionalBoolean(\n 'scaffolder.EXPERIMENTAL_gracefulShutdown',\n );\n\n const worker = await TaskWorker.create({\n taskBroker,\n actionRegistry,\n integrations,\n logger,\n auditor,\n config,\n workingDirectory,\n concurrentTasksLimit,\n permissions,\n gracefulShutdown,\n metrics,\n ...templateExtensions,\n });\n\n workers.push(worker);\n }\n\n for (const action of actions) {\n actionRegistry.register(action);\n }\n\n const launchWorkers = () => workers.forEach(worker => worker.start());\n\n const shutdownWorkers = async () => {\n await Promise.allSettled(workers.map(worker => worker.stop()));\n };\n\n if (options.lifecycle) {\n options.lifecycle.addStartupHook(launchWorkers);\n options.lifecycle.addShutdownHook(shutdownWorkers);\n } else {\n launchWorkers();\n }\n\n const dryRunner = createDryRunner({\n actionRegistry,\n integrations,\n logger,\n auditor,\n workingDirectory,\n permissions,\n config,\n metrics,\n ...templateExtensions,\n });\n\n const templateRules: TemplatePermissionRuleInput[] = Object.values(\n scaffolderTemplateRules,\n );\n const actionRules: ActionPermissionRuleInput[] = Object.values(\n scaffolderActionRules,\n );\n const taskRules: TaskPermissionRuleInput[] =\n Object.values(scaffolderTaskRules);\n\n if (permissionRules) {\n templateRules.push(\n ...permissionRules.filter(isTemplatePermissionRuleInput),\n );\n actionRules.push(...permissionRules.filter(isActionPermissionRuleInput));\n taskRules.push(...permissionRules.filter(isTaskPermissionRuleInput));\n }\n\n const isTemplateAuthorized = createConditionAuthorizer(\n Object.values(templateRules),\n );\n const isTaskAuthorized = createConditionAuthorizer(Object.values(taskRules));\n\n const taskTransformConditions: ConditionTransformer<TaskFilters> =\n createConditionTransformer(Object.values(taskRules));\n\n permissionsRegistry.addResourceType({\n resourceRef: scaffolderTemplatePermissionResourceRef,\n permissions: scaffolderTemplatePermissions,\n rules: templateRules,\n });\n\n permissionsRegistry.addResourceType({\n resourceRef: scaffolderActionPermissionResourceRef,\n permissions: scaffolderActionPermissions,\n rules: actionRules,\n });\n\n permissionsRegistry.addResourceType({\n resourceRef: scaffolderTaskPermissionResourceRef,\n permissions: scaffolderTaskPermissions,\n rules: taskRules,\n getResources: async resourceRefs => {\n return Promise.all(\n resourceRefs.map(async taskId => {\n return await taskBroker.get(taskId);\n }),\n );\n },\n });\n\n permissionsRegistry.addPermissions([\n taskCreatePermission,\n templateManagementPermission,\n ]);\n\n router\n .get(\n '/v2/templates/:namespace/:kind/:name/parameter-schema',\n async (req, res) => {\n const requestedTemplateRef = `${req.params.kind}:${req.params.namespace}/${req.params.name}`;\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'template-parameter-schema',\n request: req,\n meta: { templateRef: requestedTemplateRef },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n\n const template = await authorizeTemplate(req.params, credentials);\n\n const parameters = [template.spec.parameters ?? []].flat();\n\n const presentation = template.spec.presentation;\n\n const templateRef = `${template.kind}:${\n template.metadata.namespace || 'default'\n }/${template.metadata.name}`;\n\n await auditorEvent?.success({ meta: { templateRef: templateRef } });\n\n res.json({\n title: template.metadata.title ?? template.metadata.name,\n ...(presentation ? { presentation } : {}),\n description: template.metadata.description,\n 'ui:options': template.metadata['ui:options'],\n steps: parameters.map(schema => ({\n title:\n (schema.title as string) ??\n 'Please enter the following information',\n description: schema.description as string,\n schema,\n })),\n EXPERIMENTAL_formDecorators:\n template.spec.EXPERIMENTAL_formDecorators,\n });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n },\n )\n .get('/v2/actions', async (req, res) => {\n const auditorEvent = await auditor?.createEvent({\n eventId: 'action-fetch',\n request: req,\n });\n const credentials = await httpAuth.credentials(req);\n\n try {\n const list = await actionRegistry.list({ credentials });\n const actionsList = Array.from(list.values())\n .map(action => {\n return {\n id: action.id,\n description: action.description,\n examples: action.examples,\n schema: action.schema,\n };\n })\n .sort((a, b) => a.id.localeCompare(b.id));\n\n await auditorEvent?.success();\n\n res.json(actionsList);\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .post('/v2/tasks', async (req, res) => {\n const templateRef: string = req.body.templateRef;\n const { kind, namespace, name } = parseEntityRef(templateRef, {\n defaultKind: 'template',\n });\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n severityLevel: 'medium',\n request: req,\n meta: {\n actionType: 'create',\n templateRef: templateRef,\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n await checkPermission({\n credentials,\n permissions: [taskCreatePermission],\n permissionService: permissions,\n });\n\n const userEntityRef = auth.isPrincipal(credentials, 'user')\n ? credentials.principal.userEntityRef\n : undefined;\n\n const userEntity = userEntityRef\n ? await catalog.getEntityByRef(userEntityRef, { credentials })\n : undefined;\n\n let auditLog = `Scaffolding task for ${templateRef}`;\n if (userEntityRef) {\n auditLog += ` created by ${userEntityRef}`;\n }\n logger.info(auditLog);\n\n const values = req.body.values;\n\n const template = await authorizeTemplate(\n { kind, namespace, name },\n credentials,\n );\n\n for (const parameters of [template.spec.parameters ?? []].flat()) {\n const result = validate(values, parameters);\n\n if (!result.valid) {\n await auditorEvent?.fail({\n // TODO(Rugvip): Seems like there aren't proper types for AggregateError yet\n error: (AggregateError as any)(\n result.errors,\n 'Could not create entity',\n ),\n });\n\n res.status(400).json({ errors: result.errors });\n return;\n }\n }\n\n const secretsValid = await validateSecrets({\n template,\n secrets: req.body.secrets ?? {},\n res,\n auditorEvent,\n });\n if (!secretsValid) {\n return;\n }\n\n const baseUrl = getEntityBaseUrl(template);\n\n const taskSpec: TaskSpec = {\n apiVersion: template.apiVersion,\n steps: template.spec.steps.map((step, index) => ({\n ...step,\n id: step.id ?? `step-${index + 1}`,\n name: step.name ?? step.action,\n })),\n EXPERIMENTAL_recovery: template.spec.EXPERIMENTAL_recovery,\n output: template.spec.output ?? {},\n parameters: values,\n user: {\n entity: userEntity as UserEntity,\n ref: userEntityRef,\n },\n templateInfo: {\n entityRef: stringifyEntityRef({ kind, name, namespace }),\n baseUrl,\n entity: {\n metadata: template.metadata,\n },\n },\n };\n\n const secrets: InternalTaskSecrets = {\n ...req.body.secrets,\n backstageToken: (credentials as any).token,\n __initiatorCredentials: JSON.stringify({\n ...credentials,\n // credentials.token is nonenumerable and will not be serialized, so we need to add it explicitly\n token: (credentials as any).token,\n }),\n };\n\n const result = await taskBroker.dispatch({\n spec: taskSpec,\n createdBy: userEntityRef,\n secrets,\n });\n\n await auditorEvent?.success({ meta: { taskId: result.taskId } });\n\n res.status(201).json({ id: result.taskId });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .get('/v2/tasks', async (req, res) => {\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n request: req,\n meta: {\n actionType: 'list',\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n\n if (!taskBroker.list) {\n throw new Error(\n 'TaskBroker does not support listing tasks, please implement the list method on the TaskBroker.',\n );\n }\n\n const createdBy = parseStringsParam(req.query.createdBy, 'createdBy');\n const status = parseStringsParam(req.query.status, 'status');\n\n const order = parseStringsParam(req.query.order, 'order')?.map(item => {\n const match = item.match(/^(asc|desc):(.+)$/);\n if (!match) {\n throw new InputError(\n `Invalid order parameter \"${item}\", expected \"<asc or desc>:<field name>\"`,\n );\n }\n\n return {\n order: match[1] as 'asc' | 'desc',\n field: match[2],\n };\n });\n\n const { limit, offset } = req.query;\n\n const taskPermissionFilters = await getAuthorizeConditions({\n credentials: credentials,\n permission: taskReadPermission,\n permissionService: permissions,\n transformConditions: taskTransformConditions,\n });\n\n const tasks = await taskBroker.list({\n filters: {\n createdBy,\n status: status ? (status as TaskStatus[]) : undefined,\n },\n order,\n pagination: {\n limit,\n offset,\n },\n permissionFilters: taskPermissionFilters,\n });\n\n await auditorEvent?.success();\n\n res.status(200).json(tasks);\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .get('/v2/tasks/:taskId', async (req, res) => {\n const { taskId } = req.params;\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n request: req,\n meta: {\n actionType: 'get',\n taskId: taskId,\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n\n const task = await taskBroker.get(taskId);\n\n await checkTaskPermission({\n credentials,\n permissions: [taskReadPermission],\n permissionService: permissions,\n task: task,\n isTaskAuthorized,\n });\n\n if (!task) {\n throw new NotFoundError(`Task with id ${taskId} does not exist`);\n }\n\n await auditorEvent?.success();\n\n // Do not disclose secrets\n delete task.secrets;\n res.status(200).json(task);\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .post('/v2/tasks/:taskId/cancel', async (req, res) => {\n const { taskId } = req.params;\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n severityLevel: 'medium',\n request: req,\n meta: {\n actionType: 'cancel',\n taskId: taskId,\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n const task = await taskBroker.get(taskId);\n // Requires both read and cancel permissions\n await checkTaskPermission({\n credentials,\n permissions: [taskCancelPermission, taskReadPermission],\n permissionService: permissions,\n task: task,\n isTaskAuthorized,\n });\n\n await taskBroker.cancel?.(taskId);\n\n await auditorEvent?.success();\n\n res.status(200).json({ status: 'cancelled' });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .post('/v2/tasks/:taskId/retry', async (req, res) => {\n const { taskId } = req.params;\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n severityLevel: 'medium',\n request: req,\n meta: {\n actionType: 'retry',\n taskId: taskId,\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n const task = await taskBroker.get(taskId);\n\n // Requires both read and create permissions\n await checkPermission({\n credentials,\n permissions: [taskCreatePermission],\n permissionService: permissions,\n });\n\n await checkTaskPermission({\n credentials,\n permissions: [taskReadPermission],\n permissionService: permissions,\n task: task,\n isTaskAuthorized,\n });\n\n // Validate secrets against template schema if defined\n if (task.spec.templateInfo?.entityRef) {\n const templateEntityRef = parseEntityRef(\n task.spec.templateInfo.entityRef,\n { defaultKind: 'template' },\n );\n const template = await authorizeTemplate(\n templateEntityRef,\n credentials,\n );\n\n const secretsValid = await validateSecrets({\n template,\n secrets: req.body.secrets ?? {},\n res,\n auditorEvent,\n });\n if (!secretsValid) {\n return;\n }\n }\n\n await auditorEvent?.success();\n\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: credentials,\n targetPluginId: 'catalog',\n });\n\n const secrets: InternalTaskSecrets = {\n ...req.body.secrets,\n backstageToken: token,\n __initiatorCredentials: JSON.stringify({\n ...credentials,\n // credentials.token is nonenumerable and will not be serialized, so we need to add it explicitly\n token: (credentials as any).token,\n }),\n };\n\n await taskBroker.retry?.({ secrets, taskId });\n res.status(201).json({ id: taskId });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n });\n (router as express.Router).get(\n '/v2/tasks/:taskId/eventstream',\n async (req, res) => {\n const { taskId } = req.params;\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n request: req,\n meta: {\n actionType: 'stream',\n taskId: taskId,\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n const task = await taskBroker.get(taskId);\n\n await checkTaskPermission({\n credentials,\n permissions: [taskReadPermission],\n permissionService: permissions,\n task: task,\n isTaskAuthorized,\n });\n\n const after =\n req.query.after !== undefined ? Number(req.query.after) : undefined;\n\n logger.debug(`Event stream observing taskId '${taskId}' opened`);\n\n // Mandatory headers and http status to keep connection open\n res.writeHead(200, {\n Connection: 'keep-alive',\n 'Cache-Control': 'no-cache',\n 'Content-Type': 'text/event-stream',\n });\n\n // After client opens connection send all events as string\n const subscription = taskBroker.event$({ taskId, after }).subscribe({\n error: async error => {\n logger.error(\n `Received error from event stream when observing taskId '${taskId}', ${error}`,\n );\n await auditorEvent?.fail({ error: error });\n res.end();\n },\n next: ({ events }) => {\n let shouldUnsubscribe = false;\n for (const event of events) {\n res.write(\n `event: ${event.type}\\ndata: ${JSON.stringify(event)}\\n\\n`,\n );\n if (event.type === 'completion' && !event.isTaskRecoverable) {\n shouldUnsubscribe = true;\n }\n }\n // res.flush() is only available with the compression middleware\n res.flush?.();\n if (shouldUnsubscribe) {\n subscription.unsubscribe();\n res.end();\n }\n },\n });\n\n // When client closes connection we update the clients list\n // avoiding the disconnected one\n req.on('close', async () => {\n subscription.unsubscribe();\n logger.debug(`Event stream observing taskId '${taskId}' closed`);\n await auditorEvent?.success();\n });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n },\n );\n router\n .get('/v2/tasks/:taskId/events', async (req, res) => {\n const { taskId } = req.params;\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n request: req,\n meta: {\n actionType: 'events',\n taskId: taskId,\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n const task = await taskBroker.get(taskId);\n\n await checkTaskPermission({\n credentials,\n permissions: [taskReadPermission],\n permissionService: permissions,\n task: task,\n isTaskAuthorized,\n });\n\n const after =\n req.query.after !== undefined ? Number(req.query.after) : undefined;\n\n // cancel the request after 30 seconds. this aligns with the recommendations of RFC 6202.\n const timeout = setTimeout(() => {\n res.json([]);\n }, 30_000);\n\n // Get all known events after an id (always includes the completion event) and return the first callback\n const subscription = taskBroker.event$({ taskId, after }).subscribe({\n error: async error => {\n logger.error(\n `Received error from event stream when observing taskId '${taskId}', ${error}`,\n );\n await auditorEvent?.fail({ error: error });\n },\n next: async ({ events }) => {\n clearTimeout(timeout);\n subscription.unsubscribe();\n await auditorEvent?.success();\n res.json(events);\n },\n });\n\n // When client closes connection we update the clients list\n // avoiding the disconnected one\n req.on('close', () => {\n subscription.unsubscribe();\n clearTimeout(timeout);\n });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .post('/v2/dry-run', async (req, res) => {\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n request: req,\n meta: {\n actionType: 'dry-run',\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n await checkPermission({\n credentials,\n permissions: [taskCreatePermission],\n permissionService: permissions,\n });\n\n const bodySchema = z.object({\n template: z.unknown(),\n values: z.record(z.unknown()),\n secrets: z.record(z.string()).optional(),\n directoryContents: z.array(\n z.object({ path: z.string(), base64Content: z.string() }),\n ),\n });\n const body = await bodySchema.parseAsync(req.body).catch(e => {\n throw new InputError(`Malformed request: ${e}`);\n });\n\n const template = body.template as TemplateEntityV1beta3;\n if (!(await templateEntityV1beta3Validator.check(template))) {\n throw new InputError('Input template is not a template');\n }\n\n const userEntityRef = auth.isPrincipal(credentials, 'user')\n ? credentials.principal.userEntityRef\n : undefined;\n\n const userEntity = userEntityRef\n ? await catalog.getEntityByRef(userEntityRef, { credentials })\n : undefined;\n\n const templateRef: string = `${template.kind}:${\n template.metadata.namespace || 'default'\n }/${template.metadata.name}`;\n\n for (const parameters of [template.spec.parameters ?? []].flat()) {\n const result = validate(body.values, parameters);\n if (!result.valid) {\n await auditorEvent?.fail({\n // TODO(Rugvip): Seems like there aren't proper types for AggregateError yet\n error: (AggregateError as any)(\n result.errors,\n 'Could not execute dry run',\n ),\n meta: {\n templateRef: templateRef,\n parameters: template.spec.parameters,\n },\n });\n\n res.status(400).json({ errors: result.errors });\n return;\n }\n }\n\n const secretsValid = await validateSecrets({\n template,\n secrets: body.secrets ?? {},\n res,\n auditorEvent,\n });\n if (!secretsValid) {\n return;\n }\n\n const steps = template.spec.steps.map((step, index) => ({\n ...step,\n id: step.id ?? `step-${index + 1}`,\n name: step.name ?? step.action,\n }));\n\n const dryRunId = uuid();\n const contentsPath = resolveSafeChildPath(\n workingDirectory,\n `dry-run-content-${dryRunId}`,\n );\n const templateInfo = {\n entityRef: 'template:default/dry-run',\n entity: {\n metadata: template.metadata,\n },\n baseUrl: pathToFileURL(\n resolveSafeChildPath(contentsPath, 'template.yaml'),\n ).toString(),\n };\n\n const result = await dryRunner({\n spec: {\n apiVersion: template.apiVersion,\n steps,\n output: template.spec.output ?? {},\n parameters: body.values as JsonObject,\n user: {\n entity: userEntity as UserEntity,\n ref: userEntityRef,\n },\n },\n templateInfo: templateInfo,\n directoryContents: (body.directoryContents ?? []).map(file => ({\n path: file.path,\n content: Buffer.from(file.base64Content, 'base64'),\n })),\n secrets: {\n ...body.secrets,\n backstageToken: (credentials as any).token,\n },\n credentials,\n });\n\n await auditorEvent?.success({\n meta: {\n templateRef: templateRef,\n parameters: template.spec.parameters,\n },\n });\n\n res.status(200).json({\n ...result,\n steps,\n directoryContents: result.directoryContents.map(file => ({\n path: file.path,\n executable: file.executable,\n base64Content: file.content.toString('base64'),\n })),\n });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .post('/v2/autocomplete/:provider/:resource', async (req, res) => {\n const { token, context } = req.body;\n const { provider, resource } = req.params;\n\n if (!token) throw new InputError('Missing token query parameter');\n\n if (!autocompleteHandlers[provider]) {\n throw new InputError(`Unsupported provider: ${provider}`);\n }\n\n const { results } = await autocompleteHandlers[provider]({\n resource,\n token,\n context,\n });\n\n res.status(200).json({ results });\n })\n .get('/v2/templating-extensions', async (_req, res) => {\n res.status(200).json({\n filters: {\n ...extractFilterMetadata(createDefaultFilters({ integrations })),\n ...extractFilterMetadata(additionalTemplateFilters),\n },\n globals: {\n functions: extractGlobalFunctionMetadata(additionalTemplateGlobals),\n values: extractGlobalValueMetadata(additionalTemplateGlobals),\n },\n });\n });\n\n const app = express();\n app.set('logger', logger);\n app.use('/', router);\n\n async function authorizeTemplate(\n entityRef: CompoundEntityRef,\n credentials: BackstageCredentials,\n ) {\n const template = await findTemplate({\n catalog,\n entityRef,\n credentials,\n });\n\n if (!isSupportedTemplate(template)) {\n throw new InputError(\n `Unsupported apiVersion field in schema entity, ${\n (template as Entity).apiVersion\n }`,\n );\n }\n\n if (!permissions) {\n return template;\n }\n\n const [parameterDecision, stepDecision] =\n await permissions.authorizeConditional(\n [\n { permission: templateParameterReadPermission },\n { permission: templateStepReadPermission },\n ],\n { credentials },\n );\n\n // Authorize parameters\n if (Array.isArray(template.spec.parameters)) {\n template.spec.parameters = template.spec.parameters.filter(step =>\n isTemplateAuthorized(parameterDecision, step),\n );\n } else if (\n template.spec.parameters &&\n !isTemplateAuthorized(parameterDecision, template.spec.parameters)\n ) {\n template.spec.parameters = undefined;\n }\n\n // Authorize steps\n template.spec.steps = template.spec.steps.filter(step =>\n isTemplateAuthorized(stepDecision, step),\n );\n\n return template;\n }\n\n return app;\n}\n"],"names":["config","readDurationFromConfig","validate","InputError","router","createOpenApiRouter","express","permissions","getWorkingDirectory","ScmIntegrations","DatabaseTaskStore","StorageTaskBroker","Duration","DefaultTemplateActionRegistry","convertFiltersToRecord","convertGlobalsToRecord","TaskWorker","createDryRunner","scaffolderTemplateRules","scaffolderActionRules","scaffolderTaskRules","isTemplatePermissionRuleInput","isActionPermissionRuleInput","isTaskPermissionRuleInput","createConditionAuthorizer","createConditionTransformer","scaffolderTemplatePermissionResourceRef","scaffolderTemplatePermissions","scaffolderActionPermissionResourceRef","scaffolderActionPermissions","scaffolderTaskPermissionResourceRef","scaffolderTaskPermissions","taskCreatePermission","templateManagementPermission","parseEntityRef","checkPermission","result","getEntityBaseUrl","stringifyEntityRef","parseStringsParam","getAuthorizeConditions","taskReadPermission","checkTaskPermission","NotFoundError","taskCancelPermission","z","templateEntityV1beta3Validator","uuid","resolveSafeChildPath","pathToFileURL","extractFilterMetadata","createDefaultFilters","extractGlobalFunctionMetadata","extractGlobalValueMetadata","findTemplate","templateParameterReadPermission","templateStepReadPermission"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8KA,SAAS,oBAAoB,MAAA,EAA+B;AAC1D,EAAA,OAAO,OAAO,UAAA,KAAe,iCAAA;AAC/B;AAEA,MAAM,YAAA,GAAe,CACnBA,QAAA,EACA,GAAA,EACA,YAAA,KACG;AACH,EAAA,IAAIA,QAAA,CAAO,GAAA,CAAI,GAAG,CAAA,EAAG;AACnB,IAAA,OAAOC,6BAAA,CAAuBD,QAAA,EAAQ,EAAE,GAAA,EAAK,CAAA;AAAA,EAC/C;AACA,EAAA,OAAO,YAAA;AACT,CAAA;AAEA,SAAS,8BAA8B,MAAA,EAAyB;AAC9D,EAAA,OAAO,MAAA,CAAO,MAAA,CAAO,GAAA,CAAI,CAAA,GAAA,KAAO;AAC9B,IAAA,MAAM,QAAA,GAAW,GAAA,CAAI,QAAA,CAAS,OAAA,CAAQ,aAAa,SAAS,CAAA;AAC5D,IAAA,MAAM,aAAa,GAAA,CAAI,QAAA;AACvB,IAAA,MAAM,OAAA,GACJ,GAAA,CAAI,IAAA,KAAS,UAAA,GACT,CAAA,QAAA,EAAW,UAAU,CAAA,YAAA,CAAA,GACrB,CAAA,EAAG,QAAQ,CAAA,CAAA,EAAI,GAAA,CAAI,OAAO,CAAA,CAAA;AAChC,IAAA,OAAO;AAAA,MACL,GAAG,GAAA;AAAA,MACH,QAAA;AAAA,MACA,OAAA;AAAA,MACA,UAAU;AAAC,KACb;AAAA,EACF,CAAC,CAAA;AACH;AAEA,eAAe,gBAAgB,OAAA,EAKV;AACnB,EAAA,MAAM,EAAE,QAAA,EAAU,OAAA,EAAS,GAAA,EAAK,cAAa,GAAI,OAAA;AACjD,EAAA,IAAI,CAAC,QAAA,CAAS,IAAA,CAAK,OAAA,EAAS,MAAA,EAAQ;AAClC,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,SAASE,mBAAA,CAAS,OAAA,EAAS,QAAA,CAAS,IAAA,CAAK,QAAQ,MAAM,CAAA;AAC7D,EAAA,IAAI,OAAO,KAAA,EAAO;AAChB,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,cAAc,IAAA,CAAK;AAAA,IACvB,KAAA,EAAO,IAAIC,iBAAA,CAAW,2BAA2B;AAAA,GAClD,CAAA;AAED,EAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK;AAAA,IACnB,MAAA,EAAQ,8BAA8B,MAAM;AAAA,GAC7C,CAAA;AACD,EAAA,OAAO,KAAA;AACT;AAKA,eAAsB,aACpB,OAAA,EACyB;AACzB,EAAA,MAAMC,QAAA,GAAS,MAAMC,0BAAA,CAAoB;AAAA,IACvC,UAAA,EAAY;AAAA;AAAA,MAEVC,wBAAA,CAAQ,IAAA,CAAK,EAAE,KAAA,EAAO,QAAQ;AAAA;AAChC,GACD,CAAA;AAED,EAAA,MAAM;AAAA,IACJ,MAAA,EAAQ,YAAA;AAAA,IACR,MAAA;AAAA,IACA,QAAA;AAAA,IACA,OAAA;AAAA,IACA,UAAU,EAAC;AAAA,IACX,SAAA;AAAA,IACA,yBAAA;AAAA,IACA,yBAAA;AAAA,IACA,4BAAA;AAAA,iBACAC,aAAA;AAAA,IACA,mBAAA;AAAA,IACA,eAAA;AAAA,IACA,uBAAuB,EAAC;AAAA,IACxB,MAAA,EAAQ,aAAA;AAAA,IACR,IAAA;AAAA,IACA,QAAA;AAAA,IACA,OAAA;AAAA,IACA,eAAA;AAAA,IACA;AAAA,GACF,GAAI,OAAA;AAEJ,EAAA,MAAM,uBACJ,OAAA,CAAQ,oBAAA,IACR,OAAA,CAAQ,MAAA,CAAO,kBAAkB,iCAAiC,CAAA;AAEpE,EAAA,MAAM,SAAS,YAAA,CAAa,KAAA,CAAM,EAAE,MAAA,EAAQ,cAAc,CAAA;AAE1D,EAAA,MAAM,gBAAA,GAAmB,MAAMC,2BAAA,CAAoB,MAAA,EAAQ,MAAM,CAAA;AACjE,EAAA,MAAM,YAAA,GAAeC,2BAAA,CAAgB,UAAA,CAAW,MAAM,CAAA;AAEtD,EAAA,IAAI,UAAA;AACJ,EAAA,IAAI,CAAC,QAAQ,UAAA,EAAY;AACvB,IAAA,MAAM,iBAAA,GAAoB,MAAMC,mCAAA,CAAkB,MAAA,CAAO;AAAA,MACvD,QAAA;AAAA,MACA,MAAA,EAAQ;AAAA,KACT,CAAA;AACD,IAAA,UAAA,GAAa,IAAIC,mCAAA;AAAA,MACf,iBAAA;AAAA,MACA,MAAA;AAAA,MACA,MAAA;AAAA,MACA,IAAA;AAAA,MACA,4BAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,IAAI,SAAA,IAAa,kBAAkB,cAAA,EAAgB;AACjD,MAAA,MAAM,UAAU,YAAA,CAAa;AAAA,QAC3B,EAAA,EAAI,mBAAA;AAAA,QACJ,SAAA,EAAW,YAAA;AAAA,UACT,MAAA;AAAA,UACA,wCAAA;AAAA,UACA;AAAA,YACE,OAAA,EAAS;AAAA;AACX,SACF;AAAA,QACA,OAAA,EAAS,EAAE,OAAA,EAAS,EAAA,EAAG;AAAA,QACvB,IAAI,YAAY;AACd,UAAA,MAAM,EAAE,KAAA,EAAM,GAAI,MAAM,kBAAkB,cAAA,CAAe;AAAA,YACvD,UAAUC,cAAA,CAAS,UAAA;AAAA,cACjB,YAAA,CAAa,QAAQ,wBAAA,EAA0B;AAAA,gBAC7C,KAAA,EAAO;AAAA,eACR;AAAA,aACH,CAAE,GAAG,SAAS;AAAA,WACf,CAAA;AAED,UAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,YAAA,MAAM,iBAAA,CAAkB,aAAa,IAAI,CAAA;AACzC,YAAA,MAAA,CAAO,IAAA,CAAK,CAAA,+BAAA,EAAkC,IAAA,CAAK,MAAM,CAAA,CAAE,CAAA;AAAA,UAC7D;AAAA,QACF;AAAA,OACD,CAAA;AAAA,IACH;AAAA,EACF,CAAA,MAAO;AACL,IAAA,UAAA,GAAa,OAAA,CAAQ,UAAA;AAAA,EACvB;AAEA,EAAA,MAAM,iBAAiB,IAAIC,oDAAA;AAAA,IACzB,eAAA;AAAA,IACA;AAAA,GACF;AAEA,EAAA,MAAM,kBAAA,GAAqB;AAAA,IACzB,yBAAA,EAA2BC,iCAAA;AAAA,MACzB;AAAA,KACF;AAAA,IACA,yBAAA,EAA2BC,iCAAA;AAAA,MACzB;AAAA;AACF,GACF;AAEA,EAAA,MAAM,UAAwB,EAAC;AAC/B,EAAA,IAAI,yBAAyB,CAAA,EAAG;AAC9B,IAAA,MAAM,mBAAmB,MAAA,CAAO,kBAAA;AAAA,MAC9B;AAAA,KACF;AAEA,IAAA,MAAM,MAAA,GAAS,MAAMC,qBAAA,CAAW,MAAA,CAAO;AAAA,MACrC,UAAA;AAAA,MACA,cAAA;AAAA,MACA,YAAA;AAAA,MACA,MAAA;AAAA,MACA,OAAA;AAAA,MACA,MAAA;AAAA,MACA,gBAAA;AAAA,MACA,oBAAA;AAAA,mBACAT,aAAA;AAAA,MACA,gBAAA;AAAA,MACA,OAAA;AAAA,MACA,GAAG;AAAA,KACJ,CAAA;AAED,IAAA,OAAA,CAAQ,KAAK,MAAM,CAAA;AAAA,EACrB;AAEA,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,cAAA,CAAe,SAAS,MAAM,CAAA;AAAA,EAChC;AAEA,EAAA,MAAM,gBAAgB,MAAM,OAAA,CAAQ,QAAQ,CAAA,MAAA,KAAU,MAAA,CAAO,OAAO,CAAA;AAEpE,EAAA,MAAM,kBAAkB,YAAY;AAClC,IAAA,MAAM,OAAA,CAAQ,WAAW,OAAA,CAAQ,GAAA,CAAI,YAAU,MAAA,CAAO,IAAA,EAAM,CAAC,CAAA;AAAA,EAC/D,CAAA;AAEA,EAAA,IAAI,QAAQ,SAAA,EAAW;AACrB,IAAA,OAAA,CAAQ,SAAA,CAAU,eAAe,aAAa,CAAA;AAC9C,IAAA,OAAA,CAAQ,SAAA,CAAU,gBAAgB,eAAe,CAAA;AAAA,EACnD,CAAA,MAAO;AACL,IAAA,aAAA,EAAc;AAAA,EAChB;AAEA,EAAA,MAAM,YAAYU,+BAAA,CAAgB;AAAA,IAChC,cAAA;AAAA,IACA,YAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA;AAAA,IACA,gBAAA;AAAA,iBACAV,aAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA;AAAA,IACA,GAAG;AAAA,GACJ,CAAA;AAED,EAAA,MAAM,gBAA+C,MAAA,CAAO,MAAA;AAAA,IAC1DW;AAAA,GACF;AACA,EAAA,MAAM,cAA2C,MAAA,CAAO,MAAA;AAAA,IACtDC;AAAA,GACF;AACA,EAAA,MAAM,SAAA,GACJ,MAAA,CAAO,MAAA,CAAOC,yBAAmB,CAAA;AAEnC,EAAA,IAAI,eAAA,EAAiB;AACnB,IAAA,aAAA,CAAc,IAAA;AAAA,MACZ,GAAG,eAAA,CAAgB,MAAA,CAAOC,yCAA6B;AAAA,KACzD;AACA,IAAA,WAAA,CAAY,IAAA,CAAK,GAAG,eAAA,CAAgB,MAAA,CAAOC,uCAA2B,CAAC,CAAA;AACvE,IAAA,SAAA,CAAU,IAAA,CAAK,GAAG,eAAA,CAAgB,MAAA,CAAOC,qCAAyB,CAAC,CAAA;AAAA,EACrE;AAEA,EAAA,MAAM,oBAAA,GAAuBC,8CAAA;AAAA,IAC3B,MAAA,CAAO,OAAO,aAAa;AAAA,GAC7B;AACA,EAAA,MAAM,gBAAA,GAAmBA,8CAAA,CAA0B,MAAA,CAAO,MAAA,CAAO,SAAS,CAAC,CAAA;AAE3E,EAAA,MAAM,uBAAA,GACJC,+CAAA,CAA2B,MAAA,CAAO,MAAA,CAAO,SAAS,CAAC,CAAA;AAErD,EAAA,mBAAA,CAAoB,eAAA,CAAgB;AAAA,IAClC,WAAA,EAAaC,+CAAA;AAAA,IACb,WAAA,EAAaC,mCAAA;AAAA,IACb,KAAA,EAAO;AAAA,GACR,CAAA;AAED,EAAA,mBAAA,CAAoB,eAAA,CAAgB;AAAA,IAClC,WAAA,EAAaC,6CAAA;AAAA,IACb,WAAA,EAAaC,iCAAA;AAAA,IACb,KAAA,EAAO;AAAA,GACR,CAAA;AAED,EAAA,mBAAA,CAAoB,eAAA,CAAgB;AAAA,IAClC,WAAA,EAAaC,2CAAA;AAAA,IACb,WAAA,EAAaC,+BAAA;AAAA,IACb,KAAA,EAAO,SAAA;AAAA,IACP,YAAA,EAAc,OAAM,YAAA,KAAgB;AAClC,MAAA,OAAO,OAAA,CAAQ,GAAA;AAAA,QACb,YAAA,CAAa,GAAA,CAAI,OAAM,MAAA,KAAU;AAC/B,UAAA,OAAO,MAAM,UAAA,CAAW,GAAA,CAAI,MAAM,CAAA;AAAA,QACpC,CAAC;AAAA,OACH;AAAA,IACF;AAAA,GACD,CAAA;AAED,EAAA,mBAAA,CAAoB,cAAA,CAAe;AAAA,IACjCC,0BAAA;AAAA,IACAC;AAAA,GACD,CAAA;AAED,EAAA7B,QAAA,CACG,GAAA;AAAA,IACC,uDAAA;AAAA,IACA,OAAO,KAAK,GAAA,KAAQ;AAClB,MAAA,MAAM,oBAAA,GAAuB,CAAA,EAAG,GAAA,CAAI,MAAA,CAAO,IAAI,CAAA,CAAA,EAAI,GAAA,CAAI,MAAA,CAAO,SAAS,CAAA,CAAA,EAAI,GAAA,CAAI,MAAA,CAAO,IAAI,CAAA,CAAA;AAE1F,MAAA,MAAM,YAAA,GAAe,MAAM,OAAA,EAAS,WAAA,CAAY;AAAA,QAC9C,OAAA,EAAS,2BAAA;AAAA,QACT,OAAA,EAAS,GAAA;AAAA,QACT,IAAA,EAAM,EAAE,WAAA,EAAa,oBAAA;AAAqB,OAC3C,CAAA;AAED,MAAA,IAAI;AACF,QAAA,MAAM,WAAA,GAAc,MAAM,QAAA,CAAS,WAAA,CAAY,GAAG,CAAA;AAElD,QAAA,MAAM,QAAA,GAAW,MAAM,iBAAA,CAAkB,GAAA,CAAI,QAAQ,WAAW,CAAA;AAEhE,QAAA,MAAM,UAAA,GAAa,CAAC,QAAA,CAAS,IAAA,CAAK,cAAc,EAAE,EAAE,IAAA,EAAK;AAEzD,QAAA,MAAM,YAAA,GAAe,SAAS,IAAA,CAAK,YAAA;AAEnC,QAAA,MAAM,WAAA,GAAc,CAAA,EAAG,QAAA,CAAS,IAAI,CAAA,CAAA,EAClC,QAAA,CAAS,QAAA,CAAS,SAAA,IAAa,SACjC,CAAA,CAAA,EAAI,QAAA,CAAS,QAAA,CAAS,IAAI,CAAA,CAAA;AAE1B,QAAA,MAAM,cAAc,OAAA,CAAQ,EAAE,MAAM,EAAE,WAAA,IAA4B,CAAA;AAElE,QAAA,GAAA,CAAI,IAAA,CAAK;AAAA,UACP,KAAA,EAAO,QAAA,CAAS,QAAA,CAAS,KAAA,IAAS,SAAS,QAAA,CAAS,IAAA;AAAA,UACpD,GAAI,YAAA,GAAe,EAAE,YAAA,KAAiB,EAAC;AAAA,UACvC,WAAA,EAAa,SAAS,QAAA,CAAS,WAAA;AAAA,UAC/B,YAAA,EAAc,QAAA,CAAS,QAAA,CAAS,YAAY,CAAA;AAAA,UAC5C,KAAA,EAAO,UAAA,CAAW,GAAA,CAAI,CAAA,MAAA,MAAW;AAAA,YAC/B,KAAA,EACG,OAAO,KAAA,IACR,wCAAA;AAAA,YACF,aAAa,MAAA,CAAO,WAAA;AAAA,YACpB;AAAA,WACF,CAAE,CAAA;AAAA,UACF,2BAAA,EACE,SAAS,IAAA,CAAK;AAAA,SACjB,CAAA;AAAA,MACH,SAAS,GAAA,EAAK;AACZ,QAAA,MAAM,YAAA,EAAc,IAAA,CAAK,EAAE,KAAA,EAAO,KAAK,CAAA;AACvC,QAAA,MAAM,GAAA;AAAA,MACR;AAAA,IACF;AAAA,GACF,CACC,GAAA,CAAI,aAAA,EAAe,OAAO,KAAK,GAAA,KAAQ;AACtC,IAAA,MAAM,YAAA,GAAe,MAAM,OAAA,EAAS,WAAA,CAAY;AAAA,MAC9C,OAAA,EAAS,cAAA;AAAA,MACT,OAAA,EAAS;AAAA,KACV,CAAA;AACD,IAAA,MAAM,WAAA,GAAc,MAAM,QAAA,CAAS,WAAA,CAAY,GAAG,CAAA;AAElD,IAAA,IAAI;AACF,MAAA,MAAM,OAAO,MAAM,cAAA,CAAe,IAAA,CAAK,EAAE,aAAa,CAAA;AACtD,MAAA,MAAM,WAAA,GAAc,MAAM,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAA,CACzC,IAAI,CAAA,MAAA,KAAU;AACb,QAAA,OAAO;AAAA,UACL,IAAI,MAAA,CAAO,EAAA;AAAA,UACX,aAAa,MAAA,CAAO,WAAA;AAAA,UACpB,UAAU,MAAA,CAAO,QAAA;AAAA,UACjB,QAAQ,MAAA,CAAO;AAAA,SACjB;AAAA,MACF,CAAC,CAAA,CACA,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,EAAA,CAAG,aAAA,CAAc,CAAA,CAAE,EAAE,CAAC,CAAA;AAE1C,MAAA,MAAM,cAAc,OAAA,EAAQ;AAE5B,MAAA,GAAA,CAAI,KAAK,WAAW,CAAA;AAAA,IACtB,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,YAAA,EAAc,IAAA,CAAK,EAAE,KAAA,EAAO,KAAK,CAAA;AACvC,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF,CAAC,CAAA,CACA,IAAA,CAAK,WAAA,EAAa,OAAO,KAAK,GAAA,KAAQ;AACrC,IAAA,MAAM,WAAA,GAAsB,IAAI,IAAA,CAAK,WAAA;AACrC,IAAA,MAAM,EAAE,IAAA,EAAM,SAAA,EAAW,IAAA,EAAK,GAAI8B,4BAAe,WAAA,EAAa;AAAA,MAC5D,WAAA,EAAa;AAAA,KACd,CAAA;AAED,IAAA,MAAM,YAAA,GAAe,MAAM,OAAA,EAAS,WAAA,CAAY;AAAA,MAC9C,OAAA,EAAS,MAAA;AAAA,MACT,aAAA,EAAe,QAAA;AAAA,MACf,OAAA,EAAS,GAAA;AAAA,MACT,IAAA,EAAM;AAAA,QACJ,UAAA,EAAY,QAAA;AAAA,QACZ;AAAA;AACF,KACD,CAAA;AAED,IAAA,IAAI;AACF,MAAA,MAAM,WAAA,GAAc,MAAM,QAAA,CAAS,WAAA,CAAY,GAAG,CAAA;AAClD,MAAA,MAAMC,gCAAA,CAAgB;AAAA,QACpB,WAAA;AAAA,QACA,WAAA,EAAa,CAACH,0BAAoB,CAAA;AAAA,QAClC,iBAAA,EAAmBzB;AAAA,OACpB,CAAA;AAED,MAAA,MAAM,aAAA,GAAgB,KAAK,WAAA,CAAY,WAAA,EAAa,MAAM,CAAA,GACtD,WAAA,CAAY,UAAU,aAAA,GACtB,KAAA,CAAA;AAEJ,MAAA,MAAM,UAAA,GAAa,gBACf,MAAM,OAAA,CAAQ,eAAe,aAAA,EAAe,EAAE,WAAA,EAAa,CAAA,GAC3D,KAAA,CAAA;AAEJ,MAAA,IAAI,QAAA,GAAW,wBAAwB,WAAW,CAAA,CAAA;AAClD,MAAA,IAAI,aAAA,EAAe;AACjB,QAAA,QAAA,IAAY,eAAe,aAAa,CAAA,CAAA;AAAA,MAC1C;AACA,MAAA,MAAA,CAAO,KAAK,QAAQ,CAAA;AAEpB,MAAA,MAAM,MAAA,GAAS,IAAI,IAAA,CAAK,MAAA;AAExB,MAAA,MAAM,WAAW,MAAM,iBAAA;AAAA,QACrB,EAAE,IAAA,EAAM,SAAA,EAAW,IAAA,EAAK;AAAA,QACxB;AAAA,OACF;AAEA,MAAA,KAAA,MAAW,UAAA,IAAc,CAAC,QAAA,CAAS,IAAA,CAAK,cAAc,EAAE,CAAA,CAAE,IAAA,EAAK,EAAG;AAChE,QAAA,MAAM6B,OAAAA,GAASlC,mBAAA,CAAS,MAAA,EAAQ,UAAU,CAAA;AAE1C,QAAA,IAAI,CAACkC,QAAO,KAAA,EAAO;AACjB,UAAA,MAAM,cAAc,IAAA,CAAK;AAAA;AAAA,YAEvB,KAAA,EAAQ,cAAA;AAAA,cACNA,OAAAA,CAAO,MAAA;AAAA,cACP;AAAA;AACF,WACD,CAAA;AAED,UAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,EAAE,MAAA,EAAQA,OAAAA,CAAO,QAAQ,CAAA;AAC9C,UAAA;AAAA,QACF;AAAA,MACF;AAEA,MAAA,MAAM,YAAA,GAAe,MAAM,eAAA,CAAgB;AAAA,QACzC,QAAA;AAAA,QACA,OAAA,EAAS,GAAA,CAAI,IAAA,CAAK,OAAA,IAAW,EAAC;AAAA,QAC9B,GAAA;AAAA,QACA;AAAA,OACD,CAAA;AACD,MAAA,IAAI,CAAC,YAAA,EAAc;AACjB,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,OAAA,GAAUC,yBAAiB,QAAQ,CAAA;AAEzC,MAAA,MAAM,QAAA,GAAqB;AAAA,QACzB,YAAY,QAAA,CAAS,UAAA;AAAA,QACrB,OAAO,QAAA,CAAS,IAAA,CAAK,MAAM,GAAA,CAAI,CAAC,MAAM,KAAA,MAAW;AAAA,UAC/C,GAAG,IAAA;AAAA,UACH,EAAA,EAAI,IAAA,CAAK,EAAA,IAAM,CAAA,KAAA,EAAQ,QAAQ,CAAC,CAAA,CAAA;AAAA,UAChC,IAAA,EAAM,IAAA,CAAK,IAAA,IAAQ,IAAA,CAAK;AAAA,SAC1B,CAAE,CAAA;AAAA,QACF,qBAAA,EAAuB,SAAS,IAAA,CAAK,qBAAA;AAAA,QACrC,MAAA,EAAQ,QAAA,CAAS,IAAA,CAAK,MAAA,IAAU,EAAC;AAAA,QACjC,UAAA,EAAY,MAAA;AAAA,QACZ,IAAA,EAAM;AAAA,UACJ,MAAA,EAAQ,UAAA;AAAA,UACR,GAAA,EAAK;AAAA,SACP;AAAA,QACA,YAAA,EAAc;AAAA,UACZ,WAAWC,+BAAA,CAAmB,EAAE,IAAA,EAAM,IAAA,EAAM,WAAW,CAAA;AAAA,UACvD,OAAA;AAAA,UACA,MAAA,EAAQ;AAAA,YACN,UAAU,QAAA,CAAS;AAAA;AACrB;AACF,OACF;AAEA,MAAA,MAAM,OAAA,GAA+B;AAAA,QACnC,GAAG,IAAI,IAAA,CAAK,OAAA;AAAA,QACZ,gBAAiB,WAAA,CAAoB,KAAA;AAAA,QACrC,sBAAA,EAAwB,KAAK,SAAA,CAAU;AAAA,UACrC,GAAG,WAAA;AAAA;AAAA,UAEH,OAAQ,WAAA,CAAoB;AAAA,SAC7B;AAAA,OACH;AAEA,MAAA,MAAM,MAAA,GAAS,MAAM,UAAA,CAAW,QAAA,CAAS;AAAA,QACvC,IAAA,EAAM,QAAA;AAAA,QACN,SAAA,EAAW,aAAA;AAAA,QACX;AAAA,OACD,CAAA;AAED,MAAA,MAAM,YAAA,EAAc,QAAQ,EAAE,IAAA,EAAM,EAAE,MAAA,EAAQ,MAAA,CAAO,MAAA,EAAO,EAAG,CAAA;AAE/D,MAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,EAAE,EAAA,EAAI,MAAA,CAAO,QAAQ,CAAA;AAAA,IAC5C,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,YAAA,EAAc,IAAA,CAAK,EAAE,KAAA,EAAO,KAAK,CAAA;AACvC,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF,CAAC,CAAA,CACA,GAAA,CAAI,WAAA,EAAa,OAAO,KAAK,GAAA,KAAQ;AACpC,IAAA,MAAM,YAAA,GAAe,MAAM,OAAA,EAAS,WAAA,CAAY;AAAA,MAC9C,OAAA,EAAS,MAAA;AAAA,MACT,OAAA,EAAS,GAAA;AAAA,MACT,IAAA,EAAM;AAAA,QACJ,UAAA,EAAY;AAAA;AACd,KACD,CAAA;AAED,IAAA,IAAI;AACF,MAAA,MAAM,WAAA,GAAc,MAAM,QAAA,CAAS,WAAA,CAAY,GAAG,CAAA;AAElD,MAAA,IAAI,CAAC,WAAW,IAAA,EAAM;AACpB,QAAA,MAAM,IAAI,KAAA;AAAA,UACR;AAAA,SACF;AAAA,MACF;AAEA,MAAA,MAAM,SAAA,GAAYC,yBAAA,CAAkB,GAAA,CAAI,KAAA,CAAM,WAAW,WAAW,CAAA;AACpE,MAAA,MAAM,MAAA,GAASA,yBAAA,CAAkB,GAAA,CAAI,KAAA,CAAM,QAAQ,QAAQ,CAAA;AAE3D,MAAA,MAAM,KAAA,GAAQA,0BAAkB,GAAA,CAAI,KAAA,CAAM,OAAO,OAAO,CAAA,EAAG,IAAI,CAAA,IAAA,KAAQ;AACrE,QAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,mBAAmB,CAAA;AAC5C,QAAA,IAAI,CAAC,KAAA,EAAO;AACV,UAAA,MAAM,IAAIpC,iBAAA;AAAA,YACR,4BAA4B,IAAI,CAAA,wCAAA;AAAA,WAClC;AAAA,QACF;AAEA,QAAA,OAAO;AAAA,UACL,KAAA,EAAO,MAAM,CAAC,CAAA;AAAA,UACd,KAAA,EAAO,MAAM,CAAC;AAAA,SAChB;AAAA,MACF,CAAC,CAAA;AAED,MAAA,MAAM,EAAE,KAAA,EAAO,MAAA,EAAO,GAAI,GAAA,CAAI,KAAA;AAE9B,MAAA,MAAM,qBAAA,GAAwB,MAAMqC,uCAAA,CAAuB;AAAA,QACzD,WAAA;AAAA,QACA,UAAA,EAAYC,wBAAA;AAAA,QACZ,iBAAA,EAAmBlC,aAAA;AAAA,QACnB,mBAAA,EAAqB;AAAA,OACtB,CAAA;AAED,MAAA,MAAM,KAAA,GAAQ,MAAM,UAAA,CAAW,IAAA,CAAK;AAAA,QAClC,OAAA,EAAS;AAAA,UACP,SAAA;AAAA,UACA,MAAA,EAAQ,SAAU,MAAA,GAA0B,KAAA;AAAA,SAC9C;AAAA,QACA,KAAA;AAAA,QACA,UAAA,EAAY;AAAA,UACV,KAAA;AAAA,UACA;AAAA,SACF;AAAA,QACA,iBAAA,EAAmB;AAAA,OACpB,CAAA;AAED,MAAA,MAAM,cAAc,OAAA,EAAQ;AAE5B,MAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,KAAK,CAAA;AAAA,IAC5B,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,YAAA,EAAc,IAAA,CAAK,EAAE,KAAA,EAAO,KAAK,CAAA;AACvC,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF,CAAC,CAAA,CACA,GAAA,CAAI,mBAAA,EAAqB,OAAO,KAAK,GAAA,KAAQ;AAC5C,IAAA,MAAM,EAAE,MAAA,EAAO,GAAI,GAAA,CAAI,MAAA;AAEvB,IAAA,MAAM,YAAA,GAAe,MAAM,OAAA,EAAS,WAAA,CAAY;AAAA,MAC9C,OAAA,EAAS,MAAA;AAAA,MACT,OAAA,EAAS,GAAA;AAAA,MACT,IAAA,EAAM;AAAA,QACJ,UAAA,EAAY,KAAA;AAAA,QACZ;AAAA;AACF,KACD,CAAA;AAED,IAAA,IAAI;AACF,MAAA,MAAM,WAAA,GAAc,MAAM,QAAA,CAAS,WAAA,CAAY,GAAG,CAAA;AAElD,MAAA,MAAM,IAAA,GAAO,MAAM,UAAA,CAAW,GAAA,CAAI,MAAM,CAAA;AAExC,MAAA,MAAMmC,oCAAA,CAAoB;AAAA,QACxB,WAAA;AAAA,QACA,WAAA,EAAa,CAACD,wBAAkB,CAAA;AAAA,QAChC,iBAAA,EAAmBlC,aAAA;AAAA,QACnB,IAAA;AAAA,QACA;AAAA,OACD,CAAA;AAED,MAAA,IAAI,CAAC,IAAA,EAAM;AACT,QAAA,MAAM,IAAIoC,oBAAA,CAAc,CAAA,aAAA,EAAgB,MAAM,CAAA,eAAA,CAAiB,CAAA;AAAA,MACjE;AAEA,MAAA,MAAM,cAAc,OAAA,EAAQ;AAG5B,MAAA,OAAO,IAAA,CAAK,OAAA;AACZ,MAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AAAA,IAC3B,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,YAAA,EAAc,IAAA,CAAK,EAAE,KAAA,EAAO,KAAK,CAAA;AACvC,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF,CAAC,CAAA,CACA,IAAA,CAAK,0BAAA,EAA4B,OAAO,KAAK,GAAA,KAAQ;AACpD,IAAA,MAAM,EAAE,MAAA,EAAO,GAAI,GAAA,CAAI,MAAA;AAEvB,IAAA,MAAM,YAAA,GAAe,MAAM,OAAA,EAAS,WAAA,CAAY;AAAA,MAC9C,OAAA,EAAS,MAAA;AAAA,MACT,aAAA,EAAe,QAAA;AAAA,MACf,OAAA,EAAS,GAAA;AAAA,MACT,IAAA,EAAM;AAAA,QACJ,UAAA,EAAY,QAAA;AAAA,QACZ;AAAA;AACF,KACD,CAAA;AAED,IAAA,IAAI;AACF,MAAA,MAAM,WAAA,GAAc,MAAM,QAAA,CAAS,WAAA,CAAY,GAAG,CAAA;AAClD,MAAA,MAAM,IAAA,GAAO,MAAM,UAAA,CAAW,GAAA,CAAI,MAAM,CAAA;AAExC,MAAA,MAAMD,oCAAA,CAAoB;AAAA,QACxB,WAAA;AAAA,QACA,WAAA,EAAa,CAACE,0BAAA,EAAsBH,wBAAkB,CAAA;AAAA,QACtD,iBAAA,EAAmBlC,aAAA;AAAA,QACnB,IAAA;AAAA,QACA;AAAA,OACD,CAAA;AAED,MAAA,MAAM,UAAA,CAAW,SAAS,MAAM,CAAA;AAEhC,MAAA,MAAM,cAAc,OAAA,EAAQ;AAE5B,MAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,MAAA,EAAQ,aAAa,CAAA;AAAA,IAC9C,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,YAAA,EAAc,IAAA,CAAK,EAAE,KAAA,EAAO,KAAK,CAAA;AACvC,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF,CAAC,CAAA,CACA,IAAA,CAAK,yBAAA,EAA2B,OAAO,KAAK,GAAA,KAAQ;AACnD,IAAA,MAAM,EAAE,MAAA,EAAO,GAAI,GAAA,CAAI,MAAA;AAEvB,IAAA,MAAM,YAAA,GAAe,MAAM,OAAA,EAAS,WAAA,CAAY;AAAA,MAC9C,OAAA,EAAS,MAAA;AAAA,MACT,aAAA,EAAe,QAAA;AAAA,MACf,OAAA,EAAS,GAAA;AAAA,MACT,IAAA,EAAM;AAAA,QACJ,UAAA,EAAY,OAAA;AAAA,QACZ;AAAA;AACF,KACD,CAAA;AAED,IAAA,IAAI;AACF,MAAA,MAAM,WAAA,GAAc,MAAM,QAAA,CAAS,WAAA,CAAY,GAAG,CAAA;AAClD,MAAA,MAAM,IAAA,GAAO,MAAM,UAAA,CAAW,GAAA,CAAI,MAAM,CAAA;AAGxC,MAAA,MAAM4B,gCAAA,CAAgB;AAAA,QACpB,WAAA;AAAA,QACA,WAAA,EAAa,CAACH,0BAAoB,CAAA;AAAA,QAClC,iBAAA,EAAmBzB;AAAA,OACpB,CAAA;AAED,MAAA,MAAMmC,oCAAA,CAAoB;AAAA,QACxB,WAAA;AAAA,QACA,WAAA,EAAa,CAACD,wBAAkB,CAAA;AAAA,QAChC,iBAAA,EAAmBlC,aAAA;AAAA,QACnB,IAAA;AAAA,QACA;AAAA,OACD,CAAA;AAGD,MAAA,IAAI,IAAA,CAAK,IAAA,CAAK,YAAA,EAAc,SAAA,EAAW;AACrC,QAAA,MAAM,iBAAA,GAAoB2B,2BAAA;AAAA,UACxB,IAAA,CAAK,KAAK,YAAA,CAAa,SAAA;AAAA,UACvB,EAAE,aAAa,UAAA;AAAW,SAC5B;AACA,QAAA,MAAM,WAAW,MAAM,iBAAA;AAAA,UACrB,iBAAA;AAAA,UACA;AAAA,SACF;AAEA,QAAA,MAAM,YAAA,GAAe,MAAM,eAAA,CAAgB;AAAA,UACzC,QAAA;AAAA,UACA,OAAA,EAAS,GAAA,CAAI,IAAA,CAAK,OAAA,IAAW,EAAC;AAAA,UAC9B,GAAA;AAAA,UACA;AAAA,SACD,CAAA;AACD,QAAA,IAAI,CAAC,YAAA,EAAc;AACjB,UAAA;AAAA,QACF;AAAA,MACF;AAEA,MAAA,MAAM,cAAc,OAAA,EAAQ;AAE5B,MAAA,MAAM,EAAE,KAAA,EAAM,GAAI,MAAM,KAAK,qBAAA,CAAsB;AAAA,QACjD,UAAA,EAAY,WAAA;AAAA,QACZ,cAAA,EAAgB;AAAA,OACjB,CAAA;AAED,MAAA,MAAM,OAAA,GAA+B;AAAA,QACnC,GAAG,IAAI,IAAA,CAAK,OAAA;AAAA,QACZ,cAAA,EAAgB,KAAA;AAAA,QAChB,sBAAA,EAAwB,KAAK,SAAA,CAAU;AAAA,UACrC,GAAG,WAAA;AAAA;AAAA,UAEH,OAAQ,WAAA,CAAoB;AAAA,SAC7B;AAAA,OACH;AAEA,MAAA,MAAM,UAAA,CAAW,KAAA,GAAQ,EAAE,OAAA,EAAS,QAAQ,CAAA;AAC5C,MAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,KAAK,EAAE,EAAA,EAAI,QAAQ,CAAA;AAAA,IACrC,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,YAAA,EAAc,IAAA,CAAK,EAAE,KAAA,EAAO,KAAK,CAAA;AACvC,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF,CAAC,CAAA;AACH,EAAC9B,QAAA,CAA0B,GAAA;AAAA,IACzB,+BAAA;AAAA,IACA,OAAO,KAAK,GAAA,KAAQ;AAClB,MAAA,MAAM,EAAE,MAAA,EAAO,GAAI,GAAA,CAAI,MAAA;AAEvB,MAAA,MAAM,YAAA,GAAe,MAAM,OAAA,EAAS,WAAA,CAAY;AAAA,QAC9C,OAAA,EAAS,MAAA;AAAA,QACT,OAAA,EAAS,GAAA;AAAA,QACT,IAAA,EAAM;AAAA,UACJ,UAAA,EAAY,QAAA;AAAA,UACZ;AAAA;AACF,OACD,CAAA;AAED,MAAA,IAAI;AACF,QAAA,MAAM,WAAA,GAAc,MAAM,QAAA,CAAS,WAAA,CAAY,GAAG,CAAA;AAClD,QAAA,MAAM,IAAA,GAAO,MAAM,UAAA,CAAW,GAAA,CAAI,MAAM,CAAA;AAExC,QAAA,MAAMsC,oCAAA,CAAoB;AAAA,UACxB,WAAA;AAAA,UACA,WAAA,EAAa,CAACD,wBAAkB,CAAA;AAAA,UAChC,iBAAA,EAAmBlC,aAAA;AAAA,UACnB,IAAA;AAAA,UACA;AAAA,SACD,CAAA;AAED,QAAA,MAAM,KAAA,GACJ,IAAI,KAAA,CAAM,KAAA,KAAU,SAAY,MAAA,CAAO,GAAA,CAAI,KAAA,CAAM,KAAK,CAAA,GAAI,KAAA,CAAA;AAE5D,QAAA,MAAA,CAAO,KAAA,CAAM,CAAA,+BAAA,EAAkC,MAAM,CAAA,QAAA,CAAU,CAAA;AAG/D,QAAA,GAAA,CAAI,UAAU,GAAA,EAAK;AAAA,UACjB,UAAA,EAAY,YAAA;AAAA,UACZ,eAAA,EAAiB,UAAA;AAAA,UACjB,cAAA,EAAgB;AAAA,SACjB,CAAA;AAGD,QAAA,MAAM,YAAA,GAAe,WAAW,MAAA,CAAO,EAAE,QAAQ,KAAA,EAAO,EAAE,SAAA,CAAU;AAAA,UAClE,KAAA,EAAO,OAAM,KAAA,KAAS;AACpB,YAAA,MAAA,CAAO,KAAA;AAAA,cACL,CAAA,wDAAA,EAA2D,MAAM,CAAA,GAAA,EAAM,KAAK,CAAA;AAAA,aAC9E;AACA,YAAA,MAAM,YAAA,EAAc,IAAA,CAAK,EAAE,KAAA,EAAc,CAAA;AACzC,YAAA,GAAA,CAAI,GAAA,EAAI;AAAA,UACV,CAAA;AAAA,UACA,IAAA,EAAM,CAAC,EAAE,MAAA,EAAO,KAAM;AACpB,YAAA,IAAI,iBAAA,GAAoB,KAAA;AACxB,YAAA,KAAA,MAAW,SAAS,MAAA,EAAQ;AAC1B,cAAA,GAAA,CAAI,KAAA;AAAA,gBACF,CAAA,OAAA,EAAU,MAAM,IAAI;AAAA,MAAA,EAAW,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC;;AAAA;AAAA,eACtD;AACA,cAAA,IAAI,KAAA,CAAM,IAAA,KAAS,YAAA,IAAgB,CAAC,MAAM,iBAAA,EAAmB;AAC3D,gBAAA,iBAAA,GAAoB,IAAA;AAAA,cACtB;AAAA,YACF;AAEA,YAAA,GAAA,CAAI,KAAA,IAAQ;AACZ,YAAA,IAAI,iBAAA,EAAmB;AACrB,cAAA,YAAA,CAAa,WAAA,EAAY;AACzB,cAAA,GAAA,CAAI,GAAA,EAAI;AAAA,YACV;AAAA,UACF;AAAA,SACD,CAAA;AAID,QAAA,GAAA,CAAI,EAAA,CAAG,SAAS,YAAY;AAC1B,UAAA,YAAA,CAAa,WAAA,EAAY;AACzB,UAAA,MAAA,CAAO,KAAA,CAAM,CAAA,+BAAA,EAAkC,MAAM,CAAA,QAAA,CAAU,CAAA;AAC/D,UAAA,MAAM,cAAc,OAAA,EAAQ;AAAA,QAC9B,CAAC,CAAA;AAAA,MACH,SAAS,GAAA,EAAK;AACZ,QAAA,MAAM,YAAA,EAAc,IAAA,CAAK,EAAE,KAAA,EAAO,KAAK,CAAA;AACvC,QAAA,MAAM,GAAA;AAAA,MACR;AAAA,IACF;AAAA,GACF;AACA,EAAAH,QAAA,CACG,GAAA,CAAI,0BAAA,EAA4B,OAAO,GAAA,EAAK,GAAA,KAAQ;AACnD,IAAA,MAAM,EAAE,MAAA,EAAO,GAAI,GAAA,CAAI,MAAA;AAEvB,IAAA,MAAM,YAAA,GAAe,MAAM,OAAA,EAAS,WAAA,CAAY;AAAA,MAC9C,OAAA,EAAS,MAAA;AAAA,MACT,OAAA,EAAS,GAAA;AAAA,MACT,IAAA,EAAM;AAAA,QACJ,UAAA,EAAY,QAAA;AAAA,QACZ;AAAA;AACF,KACD,CAAA;AAED,IAAA,IAAI;AACF,MAAA,MAAM,WAAA,GAAc,MAAM,QAAA,CAAS,WAAA,CAAY,GAAG,CAAA;AAClD,MAAA,MAAM,IAAA,GAAO,MAAM,UAAA,CAAW,GAAA,CAAI,MAAM,CAAA;AAExC,MAAA,MAAMsC,oCAAA,CAAoB;AAAA,QACxB,WAAA;AAAA,QACA,WAAA,EAAa,CAACD,wBAAkB,CAAA;AAAA,QAChC,iBAAA,EAAmBlC,aAAA;AAAA,QACnB,IAAA;AAAA,QACA;AAAA,OACD,CAAA;AAED,MAAA,MAAM,KAAA,GACJ,IAAI,KAAA,CAAM,KAAA,KAAU,SAAY,MAAA,CAAO,GAAA,CAAI,KAAA,CAAM,KAAK,CAAA,GAAI,KAAA,CAAA;AAG5D,MAAA,MAAM,OAAA,GAAU,WAAW,MAAM;AAC/B,QAAA,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA;AAAA,MACb,GAAG,GAAM,CAAA;AAGT,MAAA,MAAM,YAAA,GAAe,WAAW,MAAA,CAAO,EAAE,QAAQ,KAAA,EAAO,EAAE,SAAA,CAAU;AAAA,QAClE,KAAA,EAAO,OAAM,KAAA,KAAS;AACpB,UAAA,MAAA,CAAO,KAAA;AAAA,YACL,CAAA,wDAAA,EAA2D,MAAM,CAAA,GAAA,EAAM,KAAK,CAAA;AAAA,WAC9E;AACA,UAAA,MAAM,YAAA,EAAc,IAAA,CAAK,EAAE,KAAA,EAAc,CAAA;AAAA,QAC3C,CAAA;AAAA,QACA,IAAA,EAAM,OAAO,EAAE,MAAA,EAAO,KAAM;AAC1B,UAAA,YAAA,CAAa,OAAO,CAAA;AACpB,UAAA,YAAA,CAAa,WAAA,EAAY;AACzB,UAAA,MAAM,cAAc,OAAA,EAAQ;AAC5B,UAAA,GAAA,CAAI,KAAK,MAAM,CAAA;AAAA,QACjB;AAAA,OACD,CAAA;AAID,MAAA,GAAA,CAAI,EAAA,CAAG,SAAS,MAAM;AACpB,QAAA,YAAA,CAAa,WAAA,EAAY;AACzB,QAAA,YAAA,CAAa,OAAO,CAAA;AAAA,MACtB,CAAC,CAAA;AAAA,IACH,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,YAAA,EAAc,IAAA,CAAK,EAAE,KAAA,EAAO,KAAK,CAAA;AACvC,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF,CAAC,CAAA,CACA,IAAA,CAAK,aAAA,EAAe,OAAO,KAAK,GAAA,KAAQ;AACvC,IAAA,MAAM,YAAA,GAAe,MAAM,OAAA,EAAS,WAAA,CAAY;AAAA,MAC9C,OAAA,EAAS,MAAA;AAAA,MACT,OAAA,EAAS,GAAA;AAAA,MACT,IAAA,EAAM;AAAA,QACJ,UAAA,EAAY;AAAA;AACd,KACD,CAAA;AAED,IAAA,IAAI;AACF,MAAA,MAAM,WAAA,GAAc,MAAM,QAAA,CAAS,WAAA,CAAY,GAAG,CAAA;AAClD,MAAA,MAAM4B,gCAAA,CAAgB;AAAA,QACpB,WAAA;AAAA,QACA,WAAA,EAAa,CAACH,0BAAoB,CAAA;AAAA,QAClC,iBAAA,EAAmBzB;AAAA,OACpB,CAAA;AAED,MAAA,MAAM,UAAA,GAAasC,KAAE,MAAA,CAAO;AAAA,QAC1B,QAAA,EAAUA,KAAE,OAAA,EAAQ;AAAA,QACpB,MAAA,EAAQA,IAAA,CAAE,MAAA,CAAOA,IAAA,CAAE,SAAS,CAAA;AAAA,QAC5B,SAASA,IAAA,CAAE,MAAA,CAAOA,KAAE,MAAA,EAAQ,EAAE,QAAA,EAAS;AAAA,QACvC,mBAAmBA,IAAA,CAAE,KAAA;AAAA,UACnBA,IAAA,CAAE,MAAA,CAAO,EAAE,IAAA,EAAMA,IAAA,CAAE,MAAA,EAAO,EAAG,aAAA,EAAeA,IAAA,CAAE,MAAA,EAAO,EAAG;AAAA;AAC1D,OACD,CAAA;AACD,MAAA,MAAM,IAAA,GAAO,MAAM,UAAA,CAAW,UAAA,CAAW,IAAI,IAAI,CAAA,CAAE,MAAM,CAAA,CAAA,KAAK;AAC5D,QAAA,MAAM,IAAI1C,iBAAA,CAAW,CAAA,mBAAA,EAAsB,CAAC,CAAA,CAAE,CAAA;AAAA,MAChD,CAAC,CAAA;AAED,MAAA,MAAM,WAAW,IAAA,CAAK,QAAA;AACtB,MAAA,IAAI,CAAE,MAAM2C,qDAAA,CAA+B,KAAA,CAAM,QAAQ,CAAA,EAAI;AAC3D,QAAA,MAAM,IAAI3C,kBAAW,kCAAkC,CAAA;AAAA,MACzD;AAEA,MAAA,MAAM,aAAA,GAAgB,KAAK,WAAA,CAAY,WAAA,EAAa,MAAM,CAAA,GACtD,WAAA,CAAY,UAAU,aAAA,GACtB,KAAA,CAAA;AAEJ,MAAA,MAAM,UAAA,GAAa,gBACf,MAAM,OAAA,CAAQ,eAAe,aAAA,EAAe,EAAE,WAAA,EAAa,CAAA,GAC3D,KAAA,CAAA;AAEJ,MAAA,MAAM,WAAA,GAAsB,CAAA,EAAG,QAAA,CAAS,IAAI,CAAA,CAAA,EAC1C,QAAA,CAAS,QAAA,CAAS,SAAA,IAAa,SACjC,CAAA,CAAA,EAAI,QAAA,CAAS,QAAA,CAAS,IAAI,CAAA,CAAA;AAE1B,MAAA,KAAA,MAAW,UAAA,IAAc,CAAC,QAAA,CAAS,IAAA,CAAK,cAAc,EAAE,CAAA,CAAE,IAAA,EAAK,EAAG;AAChE,QAAA,MAAMiC,OAAAA,GAASlC,mBAAA,CAAS,IAAA,CAAK,MAAA,EAAQ,UAAU,CAAA;AAC/C,QAAA,IAAI,CAACkC,QAAO,KAAA,EAAO;AACjB,UAAA,MAAM,cAAc,IAAA,CAAK;AAAA;AAAA,YAEvB,KAAA,EAAQ,cAAA;AAAA,cACNA,OAAAA,CAAO,MAAA;AAAA,cACP;AAAA,aACF;AAAA,YACA,IAAA,EAAM;AAAA,cACJ,WAAA;AAAA,cACA,UAAA,EAAY,SAAS,IAAA,CAAK;AAAA;AAC5B,WACD,CAAA;AAED,UAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK,EAAE,MAAA,EAAQA,OAAAA,CAAO,QAAQ,CAAA;AAC9C,UAAA;AAAA,QACF;AAAA,MACF;AAEA,MAAA,MAAM,YAAA,GAAe,MAAM,eAAA,CAAgB;AAAA,QACzC,QAAA;AAAA,QACA,OAAA,EAAS,IAAA,CAAK,OAAA,IAAW,EAAC;AAAA,QAC1B,GAAA;AAAA,QACA;AAAA,OACD,CAAA;AACD,MAAA,IAAI,CAAC,YAAA,EAAc;AACjB,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,QAAQ,QAAA,CAAS,IAAA,CAAK,MAAM,GAAA,CAAI,CAAC,MAAM,KAAA,MAAW;AAAA,QACtD,GAAG,IAAA;AAAA,QACH,EAAA,EAAI,IAAA,CAAK,EAAA,IAAM,CAAA,KAAA,EAAQ,QAAQ,CAAC,CAAA,CAAA;AAAA,QAChC,IAAA,EAAM,IAAA,CAAK,IAAA,IAAQ,IAAA,CAAK;AAAA,OAC1B,CAAE,CAAA;AAEF,MAAA,MAAM,WAAWW,OAAA,EAAK;AACtB,MAAA,MAAM,YAAA,GAAeC,qCAAA;AAAA,QACnB,gBAAA;AAAA,QACA,mBAAmB,QAAQ,CAAA;AAAA,OAC7B;AACA,MAAA,MAAM,YAAA,GAAe;AAAA,QACnB,SAAA,EAAW,0BAAA;AAAA,QACX,MAAA,EAAQ;AAAA,UACN,UAAU,QAAA,CAAS;AAAA,SACrB;AAAA,QACA,OAAA,EAASC,sBAAA;AAAA,UACPD,qCAAA,CAAqB,cAAc,eAAe;AAAA,UAClD,QAAA;AAAS,OACb;AAEA,MAAA,MAAM,MAAA,GAAS,MAAM,SAAA,CAAU;AAAA,QAC7B,IAAA,EAAM;AAAA,UACJ,YAAY,QAAA,CAAS,UAAA;AAAA,UACrB,KAAA;AAAA,UACA,MAAA,EAAQ,QAAA,CAAS,IAAA,CAAK,MAAA,IAAU,EAAC;AAAA,UACjC,YAAY,IAAA,CAAK,MAAA;AAAA,UACjB,IAAA,EAAM;AAAA,YACJ,MAAA,EAAQ,UAAA;AAAA,YACR,GAAA,EAAK;AAAA;AACP,SACF;AAAA,QACA,YAAA;AAAA,QACA,oBAAoB,IAAA,CAAK,iBAAA,IAAqB,EAAC,EAAG,IAAI,CAAA,IAAA,MAAS;AAAA,UAC7D,MAAM,IAAA,CAAK,IAAA;AAAA,UACX,OAAA,EAAS,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,eAAe,QAAQ;AAAA,SACnD,CAAE,CAAA;AAAA,QACF,OAAA,EAAS;AAAA,UACP,GAAG,IAAA,CAAK,OAAA;AAAA,UACR,gBAAiB,WAAA,CAAoB;AAAA,SACvC;AAAA,QACA;AAAA,OACD,CAAA;AAED,MAAA,MAAM,cAAc,OAAA,CAAQ;AAAA,QAC1B,IAAA,EAAM;AAAA,UACJ,WAAA;AAAA,UACA,UAAA,EAAY,SAAS,IAAA,CAAK;AAAA;AAC5B,OACD,CAAA;AAED,MAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK;AAAA,QACnB,GAAG,MAAA;AAAA,QACH,KAAA;AAAA,QACA,iBAAA,EAAmB,MAAA,CAAO,iBAAA,CAAkB,GAAA,CAAI,CAAA,IAAA,MAAS;AAAA,UACvD,MAAM,IAAA,CAAK,IAAA;AAAA,UACX,YAAY,IAAA,CAAK,UAAA;AAAA,UACjB,aAAA,EAAe,IAAA,CAAK,OAAA,CAAQ,QAAA,CAAS,QAAQ;AAAA,SAC/C,CAAE;AAAA,OACH,CAAA;AAAA,IACH,SAAS,GAAA,EAAK;AACZ,MAAA,MAAM,YAAA,EAAc,IAAA,CAAK,EAAE,KAAA,EAAO,KAAK,CAAA;AACvC,MAAA,MAAM,GAAA;AAAA,IACR;AAAA,EACF,CAAC,CAAA,CACA,IAAA,CAAK,sCAAA,EAAwC,OAAO,KAAK,GAAA,KAAQ;AAChE,IAAA,MAAM,EAAE,KAAA,EAAO,OAAA,EAAQ,GAAI,GAAA,CAAI,IAAA;AAC/B,IAAA,MAAM,EAAE,QAAA,EAAU,QAAA,EAAS,GAAI,GAAA,CAAI,MAAA;AAEnC,IAAA,IAAI,CAAC,KAAA,EAAO,MAAM,IAAI7C,kBAAW,+BAA+B,CAAA;AAEhE,IAAA,IAAI,CAAC,oBAAA,CAAqB,QAAQ,CAAA,EAAG;AACnC,MAAA,MAAM,IAAIA,iBAAA,CAAW,CAAA,sBAAA,EAAyB,QAAQ,CAAA,CAAE,CAAA;AAAA,IAC1D;AAEA,IAAA,MAAM,EAAE,OAAA,EAAQ,GAAI,MAAM,oBAAA,CAAqB,QAAQ,CAAA,CAAE;AAAA,MACvD,QAAA;AAAA,MACA,KAAA;AAAA,MACA;AAAA,KACD,CAAA;AAED,IAAA,GAAA,CAAI,OAAO,GAAG,CAAA,CAAE,IAAA,CAAK,EAAE,SAAS,CAAA;AAAA,EAClC,CAAC,CAAA,CACA,GAAA,CAAI,2BAAA,EAA6B,OAAO,MAAM,GAAA,KAAQ;AACrD,IAAA,GAAA,CAAI,MAAA,CAAO,GAAG,CAAA,CAAE,IAAA,CAAK;AAAA,MACnB,OAAA,EAAS;AAAA,QACP,GAAG+C,gCAAA,CAAsBC,yCAAA,CAAqB,EAAE,YAAA,EAAc,CAAC,CAAA;AAAA,QAC/D,GAAGD,iCAAsB,yBAAyB;AAAA,OACpD;AAAA,MACA,OAAA,EAAS;AAAA,QACP,SAAA,EAAWE,yCAA8B,yBAAyB,CAAA;AAAA,QAClE,MAAA,EAAQC,sCAA2B,yBAAyB;AAAA;AAC9D,KACD,CAAA;AAAA,EACH,CAAC,CAAA;AAEH,EAAA,MAAM,MAAM/C,wBAAA,EAAQ;AACpB,EAAA,GAAA,CAAI,GAAA,CAAI,UAAU,MAAM,CAAA;AACxB,EAAA,GAAA,CAAI,GAAA,CAAI,KAAKF,QAAM,CAAA;AAEnB,EAAA,eAAe,iBAAA,CACb,WACA,WAAA,EACA;AACA,IAAA,MAAM,QAAA,GAAW,MAAMkD,oBAAA,CAAa;AAAA,MAClC,OAAA;AAAA,MACA,SAAA;AAAA,MACA;AAAA,KACD,CAAA;AAED,IAAA,IAAI,CAAC,mBAAA,CAAoB,QAAQ,CAAA,EAAG;AAClC,MAAA,MAAM,IAAInD,iBAAA;AAAA,QACR,CAAA,+CAAA,EACG,SAAoB,UACvB,CAAA;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IAAI,CAACI,aAAA,EAAa;AAChB,MAAA,OAAO,QAAA;AAAA,IACT;AAEA,IAAA,MAAM,CAAC,iBAAA,EAAmB,YAAY,CAAA,GACpC,MAAMA,aAAA,CAAY,oBAAA;AAAA,MAChB;AAAA,QACE,EAAE,YAAYgD,qCAAA,EAAgC;AAAA,QAC9C,EAAE,YAAYC,gCAAA;AAA2B,OAC3C;AAAA,MACA,EAAE,WAAA;AAAY,KAChB;AAGF,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,QAAA,CAAS,IAAA,CAAK,UAAU,CAAA,EAAG;AAC3C,MAAA,QAAA,CAAS,IAAA,CAAK,UAAA,GAAa,QAAA,CAAS,IAAA,CAAK,UAAA,CAAW,MAAA;AAAA,QAAO,CAAA,IAAA,KACzD,oBAAA,CAAqB,iBAAA,EAAmB,IAAI;AAAA,OAC9C;AAAA,IACF,CAAA,MAAA,IACE,QAAA,CAAS,IAAA,CAAK,UAAA,IACd,CAAC,qBAAqB,iBAAA,EAAmB,QAAA,CAAS,IAAA,CAAK,UAAU,CAAA,EACjE;AACA,MAAA,QAAA,CAAS,KAAK,UAAA,GAAa,MAAA;AAAA,IAC7B;AAGA,IAAA,QAAA,CAAS,IAAA,CAAK,KAAA,GAAQ,QAAA,CAAS,IAAA,CAAK,KAAA,CAAM,MAAA;AAAA,MAAO,CAAA,IAAA,KAC/C,oBAAA,CAAqB,YAAA,EAAc,IAAI;AAAA,KACzC;AAEA,IAAA,OAAO,QAAA;AAAA,EACT;AAEA,EAAA,OAAO,GAAA;AACT;;;;"}
|
|
1
|
+
{"version":3,"file":"router.cjs.js","sources":["../../src/service/router.ts"],"sourcesContent":["/*\n * Copyright 2020 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 {\n AuditorService,\n AuditorServiceEvent,\n AuthService,\n BackstageCredentials,\n DatabaseService,\n HttpAuthService,\n LifecycleService,\n LoggerService,\n PermissionsRegistryService,\n PermissionsService,\n resolveSafeChildPath,\n SchedulerService,\n} from '@backstage/backend-plugin-api';\nimport { validate, ValidatorResult } from 'jsonschema';\nimport {\n CompoundEntityRef,\n Entity,\n parseEntityRef,\n stringifyEntityRef,\n UserEntity,\n} from '@backstage/catalog-model';\nimport { Config, readDurationFromConfig } from '@backstage/config';\nimport { InputError, NotFoundError } from '@backstage/errors';\nimport { ScmIntegrations } from '@backstage/integration';\n\nimport { EventsService } from '@backstage/plugin-events-node';\n\nimport {\n ConditionTransformer,\n createConditionAuthorizer,\n createConditionTransformer,\n} from '@backstage/plugin-permission-node';\nimport {\n TaskSpec,\n TemplateEntityV1beta3,\n templateEntityV1beta3Validator,\n} from '@backstage/plugin-scaffolder-common';\nimport {\n scaffolderActionPermissions,\n scaffolderTaskPermissions,\n scaffolderTemplatePermissions,\n taskCancelPermission,\n taskCreatePermission,\n taskReadPermission,\n templateManagementPermission,\n templateParameterReadPermission,\n templateStepReadPermission,\n} from '@backstage/plugin-scaffolder-common/alpha';\nimport {\n TaskBroker,\n TaskFilters,\n TaskStatus,\n TemplateAction,\n TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport {\n AutocompleteHandler,\n CreatedTemplateFilter,\n CreatedTemplateGlobal,\n scaffolderActionPermissionResourceRef,\n scaffolderTaskPermissionResourceRef,\n scaffolderTemplatePermissionResourceRef,\n WorkspaceProvider,\n} from '@backstage/plugin-scaffolder-node/alpha';\nimport { HumanDuration, JsonObject } from '@backstage/types';\nimport express from 'express';\nimport { Duration } from 'luxon';\nimport { pathToFileURL } from 'node:url';\nimport { randomUUID as uuid } from 'node:crypto';\nimport { z } from 'zod/v3';\nimport {\n DatabaseTaskStore,\n DefaultTemplateActionRegistry,\n TaskWorker,\n} from '../scaffolder';\nimport { createDryRunner } from '../scaffolder/dryrun';\nimport { StorageTaskBroker } from '../scaffolder/tasks/StorageTaskBroker';\nimport { InternalTaskSecrets } from '../scaffolder/tasks/types';\nimport { createOpenApiRouter } from '../schema/openapi';\nimport {\n checkPermission,\n checkTaskPermission,\n getAuthorizeConditions,\n} from '../util/checkPermissions';\nimport {\n findTemplate,\n getEntityBaseUrl,\n getWorkingDirectory,\n parseStringsParam,\n} from './helpers';\n\nimport {\n convertFiltersToRecord,\n convertGlobalsToRecord,\n extractFilterMetadata,\n extractGlobalFunctionMetadata,\n extractGlobalValueMetadata,\n} from '../util/templating';\nimport { createDefaultFilters } from '../lib/templating/filters/createDefaultFilters';\nimport {\n ActionPermissionRuleInput,\n isActionPermissionRuleInput,\n isTaskPermissionRuleInput,\n isTemplatePermissionRuleInput,\n ScaffolderPermissionRuleInput,\n TaskPermissionRuleInput,\n TemplatePermissionRuleInput,\n} from './permissions';\nimport { CatalogService } from '@backstage/plugin-catalog-node';\n\nimport {\n scaffolderActionRules,\n scaffolderTaskRules,\n scaffolderTemplateRules,\n} from './rules';\nimport {\n ActionsService,\n MetricsService,\n} from '@backstage/backend-plugin-api/alpha';\n\n/**\n * RouterOptions\n */\nexport interface RouterOptions {\n logger: LoggerService;\n config: Config;\n lifecycle?: LifecycleService;\n database: DatabaseService;\n catalog: CatalogService;\n scheduler?: SchedulerService;\n actions?: TemplateAction<any, any, any>[];\n /**\n * Sets the number of concurrent tasks that can be run at any given time on the TaskWorker\n * @defaultValue 10\n */\n concurrentTasksLimit?: number;\n taskBroker?: TaskBroker;\n additionalTemplateFilters?:\n | Record<string, TemplateFilter>\n | CreatedTemplateFilter<any, any>[];\n additionalTemplateGlobals?:\n | Record<string, TemplateGlobal>\n | CreatedTemplateGlobal[];\n additionalWorkspaceProviders?: Record<string, WorkspaceProvider>;\n permissions?: PermissionsService;\n permissionsRegistry: PermissionsRegistryService;\n permissionRules?: Array<ScaffolderPermissionRuleInput>;\n auth: AuthService;\n httpAuth: HttpAuthService;\n events?: EventsService;\n auditor?: AuditorService;\n autocompleteHandlers?: Record<string, AutocompleteHandler>;\n actionsRegistry: ActionsService;\n metrics: MetricsService;\n}\n\nfunction isSupportedTemplate(entity: TemplateEntityV1beta3) {\n return entity.apiVersion === 'scaffolder.backstage.io/v1beta3';\n}\n\nconst readDuration = (\n config: Config,\n key: string,\n defaultValue: HumanDuration,\n) => {\n if (config.has(key)) {\n return readDurationFromConfig(config, { key });\n }\n return defaultValue;\n};\n\nfunction formatSecretsValidationErrors(result: ValidatorResult) {\n return result.errors.map(err => {\n const property = err.property.replace(/^instance/, 'secrets');\n const secretName = err.argument;\n const message =\n err.name === 'required'\n ? `secrets.${secretName} is required`\n : `${property} ${err.message}`;\n return {\n ...err,\n property,\n message,\n instance: {},\n };\n });\n}\n\nasync function validateSecrets(options: {\n template: TemplateEntityV1beta3;\n secrets: Record<string, unknown>;\n res: express.Response;\n auditorEvent?: AuditorServiceEvent;\n}): Promise<boolean> {\n const { template, secrets, res, auditorEvent } = options;\n if (!template.spec.secrets?.schema) {\n return true;\n }\n\n const result = validate(secrets, template.spec.secrets.schema);\n if (result.valid) {\n return true;\n }\n\n await auditorEvent?.fail({\n error: new InputError('Secrets validation failed'),\n });\n\n res.status(400).json({\n errors: formatSecretsValidationErrors(result),\n });\n return false;\n}\n\n/**\n * A method to create a router for the scaffolder backend plugin.\n */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const router = await createOpenApiRouter({\n middleware: [\n // Be generous in upload size to support a wide range of templates in dry-run mode.\n express.json({ limit: '10MB' }),\n ],\n });\n\n const {\n logger: parentLogger,\n config,\n database,\n catalog,\n actions = [],\n scheduler,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n additionalWorkspaceProviders,\n permissions,\n permissionsRegistry,\n permissionRules,\n autocompleteHandlers = {},\n events: eventsService,\n auth,\n httpAuth,\n auditor,\n actionsRegistry,\n metrics,\n } = options;\n\n const concurrentTasksLimit =\n options.concurrentTasksLimit ??\n options.config.getOptionalNumber('scaffolder.concurrentTasksLimit');\n\n const logger = parentLogger.child({ plugin: 'scaffolder' });\n\n const workingDirectory = await getWorkingDirectory(config, logger);\n const integrations = ScmIntegrations.fromConfig(config);\n\n let taskBroker: TaskBroker;\n if (!options.taskBroker) {\n const databaseTaskStore = await DatabaseTaskStore.create({\n database,\n events: eventsService,\n });\n taskBroker = new StorageTaskBroker(\n databaseTaskStore,\n logger,\n config,\n auth,\n additionalWorkspaceProviders,\n auditor,\n );\n\n if (scheduler && databaseTaskStore.listStaleTasks) {\n await scheduler.scheduleTask({\n id: 'close_stale_tasks',\n frequency: readDuration(\n config,\n 'scaffolder.taskTimeoutJanitorFrequency',\n {\n minutes: 5,\n },\n ),\n timeout: { minutes: 15 },\n fn: async () => {\n const { tasks } = await databaseTaskStore.listStaleTasks({\n timeoutS: Duration.fromObject(\n readDuration(config, 'scaffolder.taskTimeout', {\n hours: 24,\n }),\n ).as('seconds'),\n });\n\n for (const task of tasks) {\n await databaseTaskStore.shutdownTask(task);\n logger.info(`Successfully closed stale task ${task.taskId}`);\n }\n },\n });\n }\n } else {\n taskBroker = options.taskBroker;\n }\n\n const actionRegistry = new DefaultTemplateActionRegistry(\n actionsRegistry,\n logger,\n );\n\n const templateExtensions = {\n additionalTemplateFilters: convertFiltersToRecord(\n additionalTemplateFilters,\n ),\n additionalTemplateGlobals: convertGlobalsToRecord(\n additionalTemplateGlobals,\n ),\n };\n\n const workers: TaskWorker[] = [];\n if (concurrentTasksLimit !== 0) {\n const gracefulShutdown = config.getOptionalBoolean(\n 'scaffolder.EXPERIMENTAL_gracefulShutdown',\n );\n\n const worker = await TaskWorker.create({\n taskBroker,\n actionRegistry,\n integrations,\n logger,\n auditor,\n config,\n workingDirectory,\n concurrentTasksLimit,\n permissions,\n gracefulShutdown,\n metrics,\n ...templateExtensions,\n });\n\n workers.push(worker);\n }\n\n for (const action of actions) {\n actionRegistry.register(action);\n }\n\n const launchWorkers = () => workers.forEach(worker => worker.start());\n\n const shutdownWorkers = async () => {\n await Promise.allSettled(workers.map(worker => worker.stop()));\n };\n\n if (options.lifecycle) {\n options.lifecycle.addStartupHook(launchWorkers);\n options.lifecycle.addShutdownHook(shutdownWorkers);\n } else {\n launchWorkers();\n }\n\n const dryRunner = createDryRunner({\n actionRegistry,\n integrations,\n logger,\n auditor,\n workingDirectory,\n permissions,\n config,\n metrics,\n ...templateExtensions,\n });\n\n const templateRules: TemplatePermissionRuleInput[] = Object.values(\n scaffolderTemplateRules,\n );\n const actionRules: ActionPermissionRuleInput[] = Object.values(\n scaffolderActionRules,\n );\n const taskRules: TaskPermissionRuleInput[] =\n Object.values(scaffolderTaskRules);\n\n if (permissionRules) {\n templateRules.push(\n ...permissionRules.filter(isTemplatePermissionRuleInput),\n );\n actionRules.push(...permissionRules.filter(isActionPermissionRuleInput));\n taskRules.push(...permissionRules.filter(isTaskPermissionRuleInput));\n }\n\n const isTemplateAuthorized = createConditionAuthorizer(\n Object.values(templateRules),\n );\n const isTaskAuthorized = createConditionAuthorizer(Object.values(taskRules));\n\n const taskTransformConditions: ConditionTransformer<TaskFilters> =\n createConditionTransformer(Object.values(taskRules));\n\n permissionsRegistry.addResourceType({\n resourceRef: scaffolderTemplatePermissionResourceRef,\n permissions: scaffolderTemplatePermissions,\n rules: templateRules,\n });\n\n permissionsRegistry.addResourceType({\n resourceRef: scaffolderActionPermissionResourceRef,\n permissions: scaffolderActionPermissions,\n rules: actionRules,\n });\n\n permissionsRegistry.addResourceType({\n resourceRef: scaffolderTaskPermissionResourceRef,\n permissions: scaffolderTaskPermissions,\n rules: taskRules,\n getResources: async resourceRefs => {\n return Promise.all(\n resourceRefs.map(async taskId => {\n return await taskBroker.get(taskId);\n }),\n );\n },\n });\n\n permissionsRegistry.addPermissions([\n taskCreatePermission,\n templateManagementPermission,\n ]);\n\n router\n .get(\n '/v2/templates/:namespace/:kind/:name/parameter-schema',\n async (req, res) => {\n const requestedTemplateRef = `${req.params.kind}:${req.params.namespace}/${req.params.name}`;\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'template-parameter-schema',\n request: req,\n meta: { templateRef: requestedTemplateRef },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n\n const template = await authorizeTemplate(req.params, credentials);\n\n const parameters = [template.spec.parameters ?? []].flat();\n\n const presentation = template.spec.presentation;\n\n const templateRef = `${template.kind}:${\n template.metadata.namespace || 'default'\n }/${template.metadata.name}`;\n\n await auditorEvent?.success({ meta: { templateRef: templateRef } });\n\n res.json({\n title: template.metadata.title ?? template.metadata.name,\n ...(presentation ? { presentation } : {}),\n description: template.metadata.description,\n 'ui:options': template.metadata['ui:options'],\n steps: parameters.map(schema => ({\n title:\n (schema.title as string) ??\n 'Please enter the following information',\n description: schema.description as string,\n schema,\n })),\n EXPERIMENTAL_formDecorators:\n template.spec.EXPERIMENTAL_formDecorators,\n });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n },\n )\n .get('/v2/actions', async (req, res) => {\n const auditorEvent = await auditor?.createEvent({\n eventId: 'action-fetch',\n request: req,\n });\n const credentials = await httpAuth.credentials(req);\n\n try {\n const list = await actionRegistry.list({ credentials });\n const actionsList = Array.from(list.values())\n .map(action => {\n return {\n id: action.id,\n description: action.description,\n examples: action.examples,\n schema: action.schema,\n };\n })\n .sort((a, b) => a.id.localeCompare(b.id));\n\n await auditorEvent?.success();\n\n res.json(actionsList);\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .post('/v2/tasks', async (req, res) => {\n const templateRef: string = req.body.templateRef;\n const { kind, namespace, name } = parseEntityRef(templateRef, {\n defaultKind: 'template',\n });\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n severityLevel: 'medium',\n request: req,\n meta: {\n actionType: 'create',\n templateRef: templateRef,\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n await checkPermission({\n credentials,\n permissions: [taskCreatePermission],\n permissionService: permissions,\n });\n\n const userEntityRef = auth.isPrincipal(credentials, 'user')\n ? credentials.principal.userEntityRef\n : undefined;\n\n const userEntity = userEntityRef\n ? await catalog.getEntityByRef(userEntityRef, { credentials })\n : undefined;\n\n let auditLog = `Scaffolding task for ${templateRef}`;\n if (userEntityRef) {\n auditLog += ` created by ${userEntityRef}`;\n }\n logger.info(auditLog);\n\n const values = req.body.values;\n\n const template = await authorizeTemplate(\n { kind, namespace, name },\n credentials,\n );\n\n for (const parameters of [template.spec.parameters ?? []].flat()) {\n const result = validate(values, parameters);\n\n if (!result.valid) {\n await auditorEvent?.fail({\n // TODO(Rugvip): Seems like there aren't proper types for AggregateError yet\n error: (AggregateError as any)(\n result.errors,\n 'Could not create entity',\n ),\n });\n\n res.status(400).json({ errors: result.errors });\n return;\n }\n }\n\n const secretsValid = await validateSecrets({\n template,\n secrets: req.body.secrets ?? {},\n res,\n auditorEvent,\n });\n if (!secretsValid) {\n return;\n }\n\n const baseUrl = getEntityBaseUrl(template);\n\n const taskSpec: TaskSpec = {\n apiVersion: template.apiVersion,\n steps: template.spec.steps.map((step, index) => ({\n ...step,\n id: step.id ?? `step-${index + 1}`,\n name: step.name ?? step.action,\n })),\n EXPERIMENTAL_recovery: template.spec.EXPERIMENTAL_recovery,\n output: template.spec.output ?? {},\n parameters: values,\n user: {\n entity: userEntity as UserEntity,\n ref: userEntityRef,\n },\n templateInfo: {\n entityRef: stringifyEntityRef({ kind, name, namespace }),\n baseUrl,\n entity: {\n metadata: template.metadata,\n },\n },\n };\n\n const secrets: InternalTaskSecrets = {\n ...req.body.secrets,\n backstageToken: (credentials as any).token,\n __initiatorCredentials: JSON.stringify({\n ...credentials,\n // credentials.token is nonenumerable and will not be serialized, so we need to add it explicitly\n token: (credentials as any).token,\n }),\n };\n\n const result = await taskBroker.dispatch({\n spec: taskSpec,\n createdBy: userEntityRef,\n secrets,\n });\n\n await auditorEvent?.success({ meta: { taskId: result.taskId } });\n\n res.status(201).json({ id: result.taskId });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .get('/v2/tasks', async (req, res) => {\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n request: req,\n meta: {\n actionType: 'list',\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n\n if (!taskBroker.list) {\n throw new Error(\n 'TaskBroker does not support listing tasks, please implement the list method on the TaskBroker.',\n );\n }\n\n const createdBy = parseStringsParam(req.query.createdBy, 'createdBy');\n const status = parseStringsParam(req.query.status, 'status');\n\n const order = parseStringsParam(req.query.order, 'order')?.map(item => {\n const match = item.match(/^(asc|desc):(.+)$/);\n if (!match) {\n throw new InputError(\n `Invalid order parameter \"${item}\", expected \"<asc or desc>:<field name>\"`,\n );\n }\n\n return {\n order: match[1] as 'asc' | 'desc',\n field: match[2],\n };\n });\n\n const { limit, offset } = req.query;\n\n const taskPermissionFilters = await getAuthorizeConditions({\n credentials: credentials,\n permission: taskReadPermission,\n permissionService: permissions,\n transformConditions: taskTransformConditions,\n });\n\n const tasks = await taskBroker.list({\n filters: {\n createdBy,\n status: status ? (status as TaskStatus[]) : undefined,\n },\n order,\n pagination: {\n limit,\n offset,\n },\n permissionFilters: taskPermissionFilters,\n });\n\n await auditorEvent?.success();\n\n res.status(200).json(tasks);\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .get('/v2/tasks/:taskId', async (req, res) => {\n const { taskId } = req.params;\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n request: req,\n meta: {\n actionType: 'get',\n taskId: taskId,\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n\n const task = await taskBroker.get(taskId);\n\n await checkTaskPermission({\n credentials,\n permissions: [taskReadPermission],\n permissionService: permissions,\n task: task,\n isTaskAuthorized,\n });\n\n if (!task) {\n throw new NotFoundError(`Task with id ${taskId} does not exist`);\n }\n\n await auditorEvent?.success();\n\n // Do not disclose secrets\n delete task.secrets;\n res.status(200).json(task);\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .post('/v2/tasks/:taskId/cancel', async (req, res) => {\n const { taskId } = req.params;\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n severityLevel: 'medium',\n request: req,\n meta: {\n actionType: 'cancel',\n taskId: taskId,\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n const task = await taskBroker.get(taskId);\n // Requires both read and cancel permissions\n await checkTaskPermission({\n credentials,\n permissions: [taskCancelPermission, taskReadPermission],\n permissionService: permissions,\n task: task,\n isTaskAuthorized,\n });\n\n await taskBroker.cancel?.(taskId);\n\n await auditorEvent?.success();\n\n res.status(200).json({ status: 'cancelled' });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .post('/v2/tasks/:taskId/retry', async (req, res) => {\n const { taskId } = req.params;\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n severityLevel: 'medium',\n request: req,\n meta: {\n actionType: 'retry',\n taskId: taskId,\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n const task = await taskBroker.get(taskId);\n\n // Requires both read and create permissions\n await checkPermission({\n credentials,\n permissions: [taskCreatePermission],\n permissionService: permissions,\n });\n\n await checkTaskPermission({\n credentials,\n permissions: [taskReadPermission],\n permissionService: permissions,\n task: task,\n isTaskAuthorized,\n });\n\n // Validate secrets against template schema if defined\n if (task.spec.templateInfo?.entityRef) {\n const templateEntityRef = parseEntityRef(\n task.spec.templateInfo.entityRef,\n { defaultKind: 'template' },\n );\n const template = await authorizeTemplate(\n templateEntityRef,\n credentials,\n );\n\n const secretsValid = await validateSecrets({\n template,\n secrets: req.body.secrets ?? {},\n res,\n auditorEvent,\n });\n if (!secretsValid) {\n return;\n }\n }\n\n await auditorEvent?.success();\n\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: credentials,\n targetPluginId: 'catalog',\n });\n\n const secrets: InternalTaskSecrets = {\n ...req.body.secrets,\n backstageToken: token,\n __initiatorCredentials: JSON.stringify({\n ...credentials,\n // credentials.token is nonenumerable and will not be serialized, so we need to add it explicitly\n token: (credentials as any).token,\n }),\n };\n\n await taskBroker.retry?.({ secrets, taskId });\n res.status(201).json({ id: taskId });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n });\n (router as express.Router).get(\n '/v2/tasks/:taskId/eventstream',\n async (req, res) => {\n const { taskId } = req.params;\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n request: req,\n meta: {\n actionType: 'stream',\n taskId: taskId,\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n const task = await taskBroker.get(taskId);\n\n await checkTaskPermission({\n credentials,\n permissions: [taskReadPermission],\n permissionService: permissions,\n task: task,\n isTaskAuthorized,\n });\n\n const after =\n req.query.after !== undefined ? Number(req.query.after) : undefined;\n\n logger.debug(`Event stream observing taskId '${taskId}' opened`);\n\n // Mandatory headers and http status to keep connection open\n res.writeHead(200, {\n Connection: 'keep-alive',\n 'Cache-Control': 'no-cache',\n 'Content-Type': 'text/event-stream',\n });\n\n // After client opens connection send all events as string\n const subscription = taskBroker.event$({ taskId, after }).subscribe({\n error: async error => {\n logger.error(\n `Received error from event stream when observing taskId '${taskId}', ${error}`,\n );\n await auditorEvent?.fail({ error: error });\n res.end();\n },\n next: ({ events }) => {\n let shouldUnsubscribe = false;\n for (const event of events) {\n res.write(\n `event: ${event.type}\\ndata: ${JSON.stringify(event)}\\n\\n`,\n );\n if (event.type === 'completion' && !event.isTaskRecoverable) {\n shouldUnsubscribe = true;\n }\n }\n // res.flush() is only available with the compression middleware\n res.flush?.();\n if (shouldUnsubscribe) {\n subscription.unsubscribe();\n res.end();\n }\n },\n });\n\n // When client closes connection we update the clients list\n // avoiding the disconnected one\n req.on('close', async () => {\n subscription.unsubscribe();\n logger.debug(`Event stream observing taskId '${taskId}' closed`);\n await auditorEvent?.success();\n });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n },\n );\n router\n .get('/v2/tasks/:taskId/events', async (req, res) => {\n const { taskId } = req.params;\n\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n request: req,\n meta: {\n actionType: 'events',\n taskId: taskId,\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n const task = await taskBroker.get(taskId);\n\n await checkTaskPermission({\n credentials,\n permissions: [taskReadPermission],\n permissionService: permissions,\n task: task,\n isTaskAuthorized,\n });\n\n const after =\n req.query.after !== undefined ? Number(req.query.after) : undefined;\n\n // cancel the request after 30 seconds. this aligns with the recommendations of RFC 6202.\n const timeout = setTimeout(() => {\n res.json([]);\n }, 30_000);\n\n // Get all known events after an id (always includes the completion event) and return the first callback\n const subscription = taskBroker.event$({ taskId, after }).subscribe({\n error: async error => {\n logger.error(\n `Received error from event stream when observing taskId '${taskId}', ${error}`,\n );\n await auditorEvent?.fail({ error: error });\n },\n next: async ({ events }) => {\n clearTimeout(timeout);\n subscription.unsubscribe();\n await auditorEvent?.success();\n res.json(events);\n },\n });\n\n // When client closes connection we update the clients list\n // avoiding the disconnected one\n req.on('close', () => {\n subscription.unsubscribe();\n clearTimeout(timeout);\n });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .post('/v2/dry-run', async (req, res) => {\n const auditorEvent = await auditor?.createEvent({\n eventId: 'task',\n request: req,\n meta: {\n actionType: 'dry-run',\n },\n });\n\n try {\n const credentials = await httpAuth.credentials(req);\n await checkPermission({\n credentials,\n permissions: [taskCreatePermission],\n permissionService: permissions,\n });\n\n const bodySchema = z.object({\n template: z.unknown(),\n values: z.record(z.unknown()),\n secrets: z.record(z.string()).optional(),\n directoryContents: z.array(\n z.object({ path: z.string(), base64Content: z.string() }),\n ),\n });\n const body = await bodySchema.parseAsync(req.body).catch(e => {\n throw new InputError(`Malformed request: ${e}`);\n });\n\n const template = body.template as TemplateEntityV1beta3;\n if (!(await templateEntityV1beta3Validator.check(template))) {\n throw new InputError('Input template is not a template');\n }\n\n const userEntityRef = auth.isPrincipal(credentials, 'user')\n ? credentials.principal.userEntityRef\n : undefined;\n\n const userEntity = userEntityRef\n ? await catalog.getEntityByRef(userEntityRef, { credentials })\n : undefined;\n\n const templateRef: string = `${template.kind}:${\n template.metadata.namespace || 'default'\n }/${template.metadata.name}`;\n\n for (const parameters of [template.spec.parameters ?? []].flat()) {\n const result = validate(body.values, parameters);\n if (!result.valid) {\n await auditorEvent?.fail({\n // TODO(Rugvip): Seems like there aren't proper types for AggregateError yet\n error: (AggregateError as any)(\n result.errors,\n 'Could not execute dry run',\n ),\n meta: {\n templateRef: templateRef,\n parameters: template.spec.parameters,\n },\n });\n\n res.status(400).json({ errors: result.errors });\n return;\n }\n }\n\n const secretsValid = await validateSecrets({\n template,\n secrets: body.secrets ?? {},\n res,\n auditorEvent,\n });\n if (!secretsValid) {\n return;\n }\n\n const steps = template.spec.steps.map((step, index) => ({\n ...step,\n id: step.id ?? `step-${index + 1}`,\n name: step.name ?? step.action,\n }));\n\n const dryRunId = uuid();\n const contentsPath = resolveSafeChildPath(\n workingDirectory,\n `dry-run-content-${dryRunId}`,\n );\n const templateInfo = {\n entityRef: 'template:default/dry-run',\n entity: {\n metadata: template.metadata,\n },\n baseUrl: pathToFileURL(\n resolveSafeChildPath(contentsPath, 'template.yaml'),\n ).toString(),\n };\n\n const result = await dryRunner({\n spec: {\n apiVersion: template.apiVersion,\n steps,\n output: template.spec.output ?? {},\n parameters: body.values as JsonObject,\n user: {\n entity: userEntity as UserEntity,\n ref: userEntityRef,\n },\n },\n templateInfo: templateInfo,\n directoryContents: (body.directoryContents ?? []).map(file => ({\n path: file.path,\n content: Buffer.from(file.base64Content, 'base64'),\n })),\n secrets: {\n ...body.secrets,\n backstageToken: (credentials as any).token,\n },\n credentials,\n });\n\n await auditorEvent?.success({\n meta: {\n templateRef: templateRef,\n parameters: template.spec.parameters,\n },\n });\n\n res.status(200).json({\n ...result,\n steps,\n directoryContents: result.directoryContents.map(file => ({\n path: file.path,\n executable: file.executable,\n base64Content: file.content.toString('base64'),\n })),\n });\n } catch (err) {\n await auditorEvent?.fail({ error: err });\n throw err;\n }\n })\n .post('/v2/autocomplete/:provider/:resource', async (req, res) => {\n const { token, context } = req.body;\n const { provider, resource } = req.params;\n\n if (!token) throw new InputError('Missing token query parameter');\n\n if (!autocompleteHandlers[provider]) {\n throw new InputError(`Unsupported provider: ${provider}`);\n }\n\n const { results } = await autocompleteHandlers[provider]({\n resource,\n token,\n context,\n });\n\n res.status(200).json({ results });\n })\n .get('/v2/templating-extensions', async (_req, res) => {\n res.status(200).json({\n filters: {\n ...extractFilterMetadata(createDefaultFilters({ integrations })),\n ...extractFilterMetadata(additionalTemplateFilters),\n },\n globals: {\n functions: extractGlobalFunctionMetadata(additionalTemplateGlobals),\n values: extractGlobalValueMetadata(additionalTemplateGlobals),\n },\n });\n });\n\n const app = express();\n app.set('logger', logger);\n app.use('/', router);\n\n async function authorizeTemplate(\n entityRef: CompoundEntityRef,\n credentials: BackstageCredentials,\n ) {\n const template = await findTemplate({\n catalog,\n entityRef,\n credentials,\n });\n\n if (!isSupportedTemplate(template)) {\n throw new InputError(\n `Unsupported apiVersion field in schema entity, ${\n (template as Entity).apiVersion\n }`,\n );\n }\n\n if (!permissions) {\n return template;\n }\n\n const [parameterDecision, stepDecision] =\n await permissions.authorizeConditional(\n [\n { permission: templateParameterReadPermission },\n { permission: templateStepReadPermission },\n ],\n { credentials },\n );\n\n // Authorize parameters\n if (Array.isArray(template.spec.parameters)) {\n template.spec.parameters = template.spec.parameters.filter(step =>\n isTemplateAuthorized(parameterDecision, step),\n );\n } else if (\n template.spec.parameters &&\n !isTemplateAuthorized(parameterDecision, template.spec.parameters)\n ) {\n template.spec.parameters = undefined;\n }\n\n // Authorize steps\n template.spec.steps = template.spec.steps.filter(step =>\n isTemplateAuthorized(stepDecision, step),\n );\n\n return template;\n }\n\n return app;\n}\n"],"names":["config","readDurationFromConfig","validate","InputError","router","createOpenApiRouter","express","permissions","getWorkingDirectory","ScmIntegrations","DatabaseTaskStore","StorageTaskBroker","Duration","DefaultTemplateActionRegistry","convertFiltersToRecord","convertGlobalsToRecord","TaskWorker","createDryRunner","scaffolderTemplateRules","scaffolderActionRules","scaffolderTaskRules","isTemplatePermissionRuleInput","isActionPermissionRuleInput","isTaskPermissionRuleInput","createConditionAuthorizer","createConditionTransformer","scaffolderTemplatePermissionResourceRef","scaffolderTemplatePermissions","scaffolderActionPermissionResourceRef","scaffolderActionPermissions","scaffolderTaskPermissionResourceRef","scaffolderTaskPermissions","taskCreatePermission","templateManagementPermission","parseEntityRef","checkPermission","result","getEntityBaseUrl","stringifyEntityRef","parseStringsParam","getAuthorizeConditions","taskReadPermission","checkTaskPermission","NotFoundError","taskCancelPermission","z","templateEntityV1beta3Validator","uuid","resolveSafeChildPath","pathToFileURL","extractFilterMetadata","createDefaultFilters","extractGlobalFunctionMetadata","extractGlobalValueMetadata","findTemplate","templateParameterReadPermission","templateStepReadPermission"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-scaffolder-backend",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.5.0-next.1",
|
|
4
4
|
"description": "The Backstage backend plugin that helps you create new things",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "backend-plugin",
|
|
@@ -79,16 +79,16 @@
|
|
|
79
79
|
"dependencies": {
|
|
80
80
|
"@backstage/backend-openapi-utils": "0.6.9-next.0",
|
|
81
81
|
"@backstage/backend-plugin-api": "1.9.1-next.0",
|
|
82
|
-
"@backstage/catalog-model": "1.8.1-next.
|
|
82
|
+
"@backstage/catalog-model": "1.8.1-next.1",
|
|
83
83
|
"@backstage/config": "1.3.8-next.0",
|
|
84
84
|
"@backstage/errors": "1.3.1-next.0",
|
|
85
85
|
"@backstage/integration": "2.0.2-next.0",
|
|
86
|
-
"@backstage/plugin-catalog-node": "2.2.1-next.
|
|
86
|
+
"@backstage/plugin-catalog-node": "2.2.1-next.1",
|
|
87
87
|
"@backstage/plugin-events-node": "0.4.22-next.0",
|
|
88
|
-
"@backstage/plugin-permission-common": "0.9.9-next.
|
|
88
|
+
"@backstage/plugin-permission-common": "0.9.9-next.1",
|
|
89
89
|
"@backstage/plugin-permission-node": "0.10.13-next.0",
|
|
90
90
|
"@backstage/plugin-scaffolder-common": "2.1.1-next.0",
|
|
91
|
-
"@backstage/plugin-scaffolder-node": "0.13.3-next.
|
|
91
|
+
"@backstage/plugin-scaffolder-node": "0.13.3-next.1",
|
|
92
92
|
"@backstage/types": "1.2.2",
|
|
93
93
|
"@types/luxon": "^3.0.0",
|
|
94
94
|
"express": "^4.22.0",
|
|
@@ -105,7 +105,6 @@
|
|
|
105
105
|
"p-queue": "^6.6.2",
|
|
106
106
|
"prom-client": "^15.0.0",
|
|
107
107
|
"triple-beam": "^1.4.1",
|
|
108
|
-
"uuid": "^11.0.0",
|
|
109
108
|
"winston": "^3.2.1",
|
|
110
109
|
"winston-transport": "^4.7.0",
|
|
111
110
|
"yaml": "^2.0.0",
|
|
@@ -114,9 +113,9 @@
|
|
|
114
113
|
"zod-to-json-schema": "^3.25.1"
|
|
115
114
|
},
|
|
116
115
|
"devDependencies": {
|
|
117
|
-
"@backstage/backend-defaults": "0.17.1-next.
|
|
118
|
-
"@backstage/backend-test-utils": "1.11.3-next.
|
|
119
|
-
"@backstage/cli": "0.36.2-next.
|
|
116
|
+
"@backstage/backend-defaults": "0.17.1-next.1",
|
|
117
|
+
"@backstage/backend-test-utils": "1.11.3-next.1",
|
|
118
|
+
"@backstage/cli": "0.36.2-next.1",
|
|
120
119
|
"@backstage/plugin-scaffolder-node-test-utils": "0.3.11-next.0",
|
|
121
120
|
"@backstage/repo-tools": "0.17.2-next.0",
|
|
122
121
|
"@types/express": "^4.17.6",
|