@backstage/plugin-scaffolder-backend 1.27.0-next.2 → 1.27.0-next.3
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 +32 -0
- package/dist/ScaffolderPlugin.cjs.js +1 -0
- package/dist/ScaffolderPlugin.cjs.js.map +1 -1
- package/dist/index.cjs.js +2 -0
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +21 -1
- package/dist/scaffolder/actions/builtin/catalog/fetch.cjs.js +11 -11
- package/dist/scaffolder/actions/builtin/catalog/fetch.cjs.js.map +1 -1
- package/dist/scaffolder/actions/builtin/catalog/write.cjs.js +4 -4
- package/dist/scaffolder/actions/builtin/catalog/write.cjs.js.map +1 -1
- package/dist/scaffolder/actions/builtin/createBuiltinActions.cjs.js +2 -0
- package/dist/scaffolder/actions/builtin/createBuiltinActions.cjs.js.map +1 -1
- package/dist/scaffolder/actions/builtin/debug/log.cjs.js +4 -4
- package/dist/scaffolder/actions/builtin/debug/log.cjs.js.map +1 -1
- package/dist/scaffolder/actions/builtin/filesystem/read.cjs.js +68 -0
- package/dist/scaffolder/actions/builtin/filesystem/read.cjs.js.map +1 -0
- package/dist/scaffolder/dryrun/DecoratedActionsRegistry.cjs.js +1 -0
- package/dist/scaffolder/dryrun/DecoratedActionsRegistry.cjs.js.map +1 -1
- package/dist/scaffolder/dryrun/createDryRunner.cjs.js +10 -12
- package/dist/scaffolder/dryrun/createDryRunner.cjs.js.map +1 -1
- package/dist/service/router.cjs.js +26 -8
- package/dist/service/router.cjs.js.map +1 -1
- package/dist/service/rules.cjs.js +11 -11
- package/dist/service/rules.cjs.js.map +1 -1
- package/package.json +29 -20
- package/alpha/package.json +0 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# @backstage/plugin-scaffolder-backend
|
|
2
2
|
|
|
3
|
+
## 1.27.0-next.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 7ab3371: Modified `createDryRunner` and corresponding route to include `templateMetaData` inside the `templateInfo`. This allows custom action writers to access things like `templateInfo.entity.metadata.name` via the action context while executing templates using the dry run framework.
|
|
8
|
+
- 2dae341: Add new `fs:readdir` action to list current content of the workspace
|
|
9
|
+
- Updated dependencies
|
|
10
|
+
- @backstage/plugin-scaffolder-common@1.5.7-next.0
|
|
11
|
+
- @backstage/plugin-bitbucket-cloud-common@0.2.25-next.0
|
|
12
|
+
- @backstage/backend-defaults@0.5.3-next.3
|
|
13
|
+
- @backstage/backend-plugin-api@1.0.2-next.2
|
|
14
|
+
- @backstage/catalog-client@1.8.0-next.1
|
|
15
|
+
- @backstage/catalog-model@1.7.0
|
|
16
|
+
- @backstage/config@1.2.0
|
|
17
|
+
- @backstage/errors@1.2.4
|
|
18
|
+
- @backstage/integration@1.15.1
|
|
19
|
+
- @backstage/types@1.1.1
|
|
20
|
+
- @backstage/plugin-auth-node@0.5.4-next.2
|
|
21
|
+
- @backstage/plugin-catalog-backend-module-scaffolder-entity-model@0.2.2-next.3
|
|
22
|
+
- @backstage/plugin-catalog-node@1.14.0-next.2
|
|
23
|
+
- @backstage/plugin-permission-common@0.8.1
|
|
24
|
+
- @backstage/plugin-permission-node@0.8.5-next.2
|
|
25
|
+
- @backstage/plugin-scaffolder-backend-module-azure@0.2.2-next.3
|
|
26
|
+
- @backstage/plugin-scaffolder-backend-module-bitbucket@0.3.2-next.3
|
|
27
|
+
- @backstage/plugin-scaffolder-backend-module-bitbucket-cloud@0.2.2-next.3
|
|
28
|
+
- @backstage/plugin-scaffolder-backend-module-bitbucket-server@0.2.2-next.3
|
|
29
|
+
- @backstage/plugin-scaffolder-backend-module-gerrit@0.2.2-next.3
|
|
30
|
+
- @backstage/plugin-scaffolder-backend-module-gitea@0.2.2-next.3
|
|
31
|
+
- @backstage/plugin-scaffolder-backend-module-github@0.5.2-next.3
|
|
32
|
+
- @backstage/plugin-scaffolder-backend-module-gitlab@0.6.1-next.3
|
|
33
|
+
- @backstage/plugin-scaffolder-node@0.5.1-next.3
|
|
34
|
+
|
|
3
35
|
## 1.27.0-next.2
|
|
4
36
|
|
|
5
37
|
### Patch Changes
|
|
@@ -16,6 +16,7 @@ var template = require('./scaffolder/actions/builtin/fetch/template.cjs.js');
|
|
|
16
16
|
var templateFile = require('./scaffolder/actions/builtin/fetch/templateFile.cjs.js');
|
|
17
17
|
var _delete = require('./scaffolder/actions/builtin/filesystem/delete.cjs.js');
|
|
18
18
|
var rename = require('./scaffolder/actions/builtin/filesystem/rename.cjs.js');
|
|
19
|
+
require('./scaffolder/actions/builtin/filesystem/read.cjs.js');
|
|
19
20
|
require('@backstage/plugin-scaffolder-backend-module-github');
|
|
20
21
|
require('@backstage/plugin-scaffolder-backend-module-azure');
|
|
21
22
|
require('@backstage/plugin-scaffolder-backend-module-bitbucket');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScaffolderPlugin.cjs.js","sources":["../src/ScaffolderPlugin.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 createBackendPlugin,\n coreServices,\n} from '@backstage/backend-plugin-api';\nimport { loggerToWinstonLogger } from '@backstage/backend-common';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha';\nimport {\n TaskBroker,\n TemplateAction,\n TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport {\n AutocompleteHandler,\n scaffolderActionsExtensionPoint,\n scaffolderAutocompleteExtensionPoint,\n scaffolderTaskBrokerExtensionPoint,\n scaffolderTemplatingExtensionPoint,\n scaffolderWorkspaceProviderExtensionPoint,\n WorkspaceProvider,\n} from '@backstage/plugin-scaffolder-node/alpha';\nimport {\n createCatalogRegisterAction,\n createCatalogWriteAction,\n createDebugLogAction,\n createFetchCatalogEntityAction,\n createFetchPlainAction,\n createFetchPlainFileAction,\n createFetchTemplateAction,\n createFetchTemplateFileAction,\n createFilesystemDeleteAction,\n createFilesystemRenameAction,\n createWaitAction,\n} from './scaffolder';\nimport { createRouter } from './service/router';\n\n/**\n * Scaffolder plugin\n *\n * @public\n */\nexport const scaffolderPlugin = createBackendPlugin({\n pluginId: 'scaffolder',\n register(env) {\n const addedActions = new Array<TemplateAction<any, any>>();\n env.registerExtensionPoint(scaffolderActionsExtensionPoint, {\n addActions(...newActions: TemplateAction<any>[]) {\n addedActions.push(...newActions);\n },\n });\n\n let taskBroker: TaskBroker | undefined;\n env.registerExtensionPoint(scaffolderTaskBrokerExtensionPoint, {\n setTaskBroker(newTaskBroker) {\n if (taskBroker) {\n throw new Error('Task broker may only be set once');\n }\n taskBroker = newTaskBroker;\n },\n });\n\n const additionalTemplateFilters: Record<string, TemplateFilter> = {};\n const additionalTemplateGlobals: Record<string, TemplateGlobal> = {};\n env.registerExtensionPoint(scaffolderTemplatingExtensionPoint, {\n addTemplateFilters(newFilters) {\n Object.assign(additionalTemplateFilters, newFilters);\n },\n addTemplateGlobals(newGlobals) {\n Object.assign(additionalTemplateGlobals, newGlobals);\n },\n });\n\n const autocompleteHandlers: Record<string, AutocompleteHandler> = {};\n env.registerExtensionPoint(scaffolderAutocompleteExtensionPoint, {\n addAutocompleteProvider(provider) {\n autocompleteHandlers[provider.id] = provider.handler;\n },\n });\n\n const additionalWorkspaceProviders: Record<string, WorkspaceProvider> = {};\n env.registerExtensionPoint(scaffolderWorkspaceProviderExtensionPoint, {\n addProviders(provider) {\n Object.assign(additionalWorkspaceProviders, provider);\n },\n });\n\n env.registerInit({\n deps: {\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n lifecycle: coreServices.rootLifecycle,\n reader: coreServices.urlReader,\n permissions: coreServices.permissions,\n database: coreServices.database,\n auth: coreServices.auth,\n discovery: coreServices.discovery,\n httpRouter: coreServices.httpRouter,\n httpAuth: coreServices.httpAuth,\n catalogClient: catalogServiceRef,\n },\n async init({\n logger,\n config,\n lifecycle,\n reader,\n database,\n auth,\n discovery,\n httpRouter,\n httpAuth,\n catalogClient,\n permissions,\n }) {\n const log = loggerToWinstonLogger(logger);\n const integrations = ScmIntegrations.fromConfig(config);\n\n const actions = [\n // actions provided from other modules\n ...addedActions,\n\n // built-in actions for the scaffolder\n createFetchPlainAction({\n reader,\n integrations,\n }),\n createFetchPlainFileAction({\n reader,\n integrations,\n }),\n createFetchTemplateAction({\n integrations,\n reader,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n }),\n createFetchTemplateFileAction({\n integrations,\n reader,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n }),\n createDebugLogAction(),\n createWaitAction(),\n // todo(blam): maybe these should be a -catalog module?\n createCatalogRegisterAction({ catalogClient, integrations, auth }),\n createFetchCatalogEntityAction({ catalogClient, auth }),\n createCatalogWriteAction(),\n createFilesystemDeleteAction(),\n createFilesystemRenameAction(),\n ];\n\n const actionIds = actions.map(action => action.id).join(', ');\n\n log.info(\n `Starting scaffolder with the following actions enabled ${actionIds}`,\n );\n\n const router = await createRouter({\n logger: log,\n config,\n database,\n catalogClient,\n reader,\n lifecycle,\n actions,\n taskBroker,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n auth,\n httpAuth,\n discovery,\n permissions,\n autocompleteHandlers,\n additionalWorkspaceProviders,\n });\n httpRouter.use(router);\n },\n });\n },\n});\n"],"names":["createBackendPlugin","scaffolderActionsExtensionPoint","scaffolderTaskBrokerExtensionPoint","scaffolderTemplatingExtensionPoint","scaffolderAutocompleteExtensionPoint","scaffolderWorkspaceProviderExtensionPoint","coreServices","catalogServiceRef","log","loggerToWinstonLogger","ScmIntegrations","createFetchPlainAction","createFetchPlainFileAction","createFetchTemplateAction","createFetchTemplateFileAction","createDebugLogAction","createWaitAction","createCatalogRegisterAction","createFetchCatalogEntityAction","createCatalogWriteAction","createFilesystemDeleteAction","createFilesystemRenameAction","router","createRouter"],"mappings":"
|
|
1
|
+
{"version":3,"file":"ScaffolderPlugin.cjs.js","sources":["../src/ScaffolderPlugin.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 createBackendPlugin,\n coreServices,\n} from '@backstage/backend-plugin-api';\nimport { loggerToWinstonLogger } from '@backstage/backend-common';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { catalogServiceRef } from '@backstage/plugin-catalog-node/alpha';\nimport {\n TaskBroker,\n TemplateAction,\n TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport {\n AutocompleteHandler,\n scaffolderActionsExtensionPoint,\n scaffolderAutocompleteExtensionPoint,\n scaffolderTaskBrokerExtensionPoint,\n scaffolderTemplatingExtensionPoint,\n scaffolderWorkspaceProviderExtensionPoint,\n WorkspaceProvider,\n} from '@backstage/plugin-scaffolder-node/alpha';\nimport {\n createCatalogRegisterAction,\n createCatalogWriteAction,\n createDebugLogAction,\n createFetchCatalogEntityAction,\n createFetchPlainAction,\n createFetchPlainFileAction,\n createFetchTemplateAction,\n createFetchTemplateFileAction,\n createFilesystemDeleteAction,\n createFilesystemRenameAction,\n createWaitAction,\n} from './scaffolder';\nimport { createRouter } from './service/router';\n\n/**\n * Scaffolder plugin\n *\n * @public\n */\nexport const scaffolderPlugin = createBackendPlugin({\n pluginId: 'scaffolder',\n register(env) {\n const addedActions = new Array<TemplateAction<any, any>>();\n env.registerExtensionPoint(scaffolderActionsExtensionPoint, {\n addActions(...newActions: TemplateAction<any>[]) {\n addedActions.push(...newActions);\n },\n });\n\n let taskBroker: TaskBroker | undefined;\n env.registerExtensionPoint(scaffolderTaskBrokerExtensionPoint, {\n setTaskBroker(newTaskBroker) {\n if (taskBroker) {\n throw new Error('Task broker may only be set once');\n }\n taskBroker = newTaskBroker;\n },\n });\n\n const additionalTemplateFilters: Record<string, TemplateFilter> = {};\n const additionalTemplateGlobals: Record<string, TemplateGlobal> = {};\n env.registerExtensionPoint(scaffolderTemplatingExtensionPoint, {\n addTemplateFilters(newFilters) {\n Object.assign(additionalTemplateFilters, newFilters);\n },\n addTemplateGlobals(newGlobals) {\n Object.assign(additionalTemplateGlobals, newGlobals);\n },\n });\n\n const autocompleteHandlers: Record<string, AutocompleteHandler> = {};\n env.registerExtensionPoint(scaffolderAutocompleteExtensionPoint, {\n addAutocompleteProvider(provider) {\n autocompleteHandlers[provider.id] = provider.handler;\n },\n });\n\n const additionalWorkspaceProviders: Record<string, WorkspaceProvider> = {};\n env.registerExtensionPoint(scaffolderWorkspaceProviderExtensionPoint, {\n addProviders(provider) {\n Object.assign(additionalWorkspaceProviders, provider);\n },\n });\n\n env.registerInit({\n deps: {\n logger: coreServices.logger,\n config: coreServices.rootConfig,\n lifecycle: coreServices.rootLifecycle,\n reader: coreServices.urlReader,\n permissions: coreServices.permissions,\n database: coreServices.database,\n auth: coreServices.auth,\n discovery: coreServices.discovery,\n httpRouter: coreServices.httpRouter,\n httpAuth: coreServices.httpAuth,\n catalogClient: catalogServiceRef,\n },\n async init({\n logger,\n config,\n lifecycle,\n reader,\n database,\n auth,\n discovery,\n httpRouter,\n httpAuth,\n catalogClient,\n permissions,\n }) {\n const log = loggerToWinstonLogger(logger);\n const integrations = ScmIntegrations.fromConfig(config);\n\n const actions = [\n // actions provided from other modules\n ...addedActions,\n\n // built-in actions for the scaffolder\n createFetchPlainAction({\n reader,\n integrations,\n }),\n createFetchPlainFileAction({\n reader,\n integrations,\n }),\n createFetchTemplateAction({\n integrations,\n reader,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n }),\n createFetchTemplateFileAction({\n integrations,\n reader,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n }),\n createDebugLogAction(),\n createWaitAction(),\n // todo(blam): maybe these should be a -catalog module?\n createCatalogRegisterAction({ catalogClient, integrations, auth }),\n createFetchCatalogEntityAction({ catalogClient, auth }),\n createCatalogWriteAction(),\n createFilesystemDeleteAction(),\n createFilesystemRenameAction(),\n ];\n\n const actionIds = actions.map(action => action.id).join(', ');\n\n log.info(\n `Starting scaffolder with the following actions enabled ${actionIds}`,\n );\n\n const router = await createRouter({\n logger: log,\n config,\n database,\n catalogClient,\n reader,\n lifecycle,\n actions,\n taskBroker,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n auth,\n httpAuth,\n discovery,\n permissions,\n autocompleteHandlers,\n additionalWorkspaceProviders,\n });\n httpRouter.use(router);\n },\n });\n },\n});\n"],"names":["createBackendPlugin","scaffolderActionsExtensionPoint","scaffolderTaskBrokerExtensionPoint","scaffolderTemplatingExtensionPoint","scaffolderAutocompleteExtensionPoint","scaffolderWorkspaceProviderExtensionPoint","coreServices","catalogServiceRef","log","loggerToWinstonLogger","ScmIntegrations","createFetchPlainAction","createFetchPlainFileAction","createFetchTemplateAction","createFetchTemplateFileAction","createDebugLogAction","createWaitAction","createCatalogRegisterAction","createFetchCatalogEntityAction","createCatalogWriteAction","createFilesystemDeleteAction","createFilesystemRenameAction","router","createRouter"],"mappings":"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"}
|
package/dist/index.cjs.js
CHANGED
|
@@ -15,6 +15,7 @@ var template = require('./scaffolder/actions/builtin/fetch/template.cjs.js');
|
|
|
15
15
|
var templateFile = require('./scaffolder/actions/builtin/fetch/templateFile.cjs.js');
|
|
16
16
|
var _delete = require('./scaffolder/actions/builtin/filesystem/delete.cjs.js');
|
|
17
17
|
var rename = require('./scaffolder/actions/builtin/filesystem/rename.cjs.js');
|
|
18
|
+
var read = require('./scaffolder/actions/builtin/filesystem/read.cjs.js');
|
|
18
19
|
var deprecated = require('./scaffolder/actions/deprecated.cjs.js');
|
|
19
20
|
var TemplateActionRegistry = require('./scaffolder/actions/TemplateActionRegistry.cjs.js');
|
|
20
21
|
var DatabaseTaskStore = require('./scaffolder/tasks/DatabaseTaskStore.cjs.js');
|
|
@@ -38,6 +39,7 @@ exports.createFetchTemplateAction = template.createFetchTemplateAction;
|
|
|
38
39
|
exports.createFetchTemplateFileAction = templateFile.createFetchTemplateFileAction;
|
|
39
40
|
exports.createFilesystemDeleteAction = _delete.createFilesystemDeleteAction;
|
|
40
41
|
exports.createFilesystemRenameAction = rename.createFilesystemRenameAction;
|
|
42
|
+
exports.createFilesystemReadDirAction = read.createFilesystemReadDirAction;
|
|
41
43
|
exports.createGithubActionsDispatchAction = deprecated.createGithubActionsDispatchAction;
|
|
42
44
|
exports.createGithubDeployKeyAction = deprecated.createGithubDeployKeyAction;
|
|
43
45
|
exports.createGithubEnvironmentAction = deprecated.createGithubEnvironmentAction;
|
package/dist/index.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -256,6 +256,26 @@ declare const createFilesystemRenameAction: () => _backstage_plugin_scaffolder_n
|
|
|
256
256
|
}>;
|
|
257
257
|
}, _backstage_types.JsonObject>;
|
|
258
258
|
|
|
259
|
+
/**
|
|
260
|
+
* Creates new action that enables reading directories in the workspace.
|
|
261
|
+
* @public
|
|
262
|
+
*/
|
|
263
|
+
declare const createFilesystemReadDirAction: () => _backstage_plugin_scaffolder_node.TemplateAction<{
|
|
264
|
+
paths: string[];
|
|
265
|
+
recursive?: boolean | undefined;
|
|
266
|
+
}, {
|
|
267
|
+
files: {
|
|
268
|
+
name: string;
|
|
269
|
+
path: string;
|
|
270
|
+
fullPath: string;
|
|
271
|
+
}[];
|
|
272
|
+
folders: {
|
|
273
|
+
name: string;
|
|
274
|
+
path: string;
|
|
275
|
+
fullPath: string;
|
|
276
|
+
}[];
|
|
277
|
+
}>;
|
|
278
|
+
|
|
259
279
|
/**
|
|
260
280
|
* @public
|
|
261
281
|
* @deprecated use import from `@backstage/plugin-scaffolder-backend-module-github` instead
|
|
@@ -941,4 +961,4 @@ declare const fetchContents: typeof fetchContents$1;
|
|
|
941
961
|
*/
|
|
942
962
|
declare const ScaffolderEntitiesProcessor: typeof ScaffolderEntitiesProcessor$1;
|
|
943
963
|
|
|
944
|
-
export { type ActionContext, type ActionPermissionRuleInput, type CreateBuiltInActionsOptions, type CreateGithubPullRequestActionOptions, type CreateWorkerOptions, type CurrentClaimedTask, DatabaseTaskStore, type DatabaseTaskStoreOptions, type RouterOptions, type RunCommandOptions, ScaffolderEntitiesProcessor, type SerializedTask, type SerializedTaskEvent, type TaskBroker, type TaskBrokerDispatchOptions, type TaskBrokerDispatchResult, type TaskCompletionState, type TaskContext, type TaskEventType, TaskManager, type TaskSecrets, type TaskStatus, type TaskStore, type TaskStoreCreateTaskOptions, type TaskStoreCreateTaskResult, type TaskStoreEmitOptions, type TaskStoreListEventsOptions, type TaskStoreRecoverTaskOptions, type TaskStoreShutDownTaskOptions, TaskWorker, type TemplateAction, TemplateActionRegistry, type TemplateFilter, type TemplateGlobal, type TemplatePermissionRuleInput, createBuiltinActions, createCatalogRegisterAction, createCatalogWriteAction, createDebugLogAction, createFetchCatalogEntityAction, createFetchPlainAction, createFetchPlainFileAction, createFetchTemplateAction, createFetchTemplateFileAction, createFilesystemDeleteAction, createFilesystemRenameAction, createGithubActionsDispatchAction, createGithubDeployKeyAction, createGithubEnvironmentAction, createGithubIssuesLabelAction, createGithubRepoCreateAction, createGithubRepoPushAction, createGithubWebhookAction, createPublishAzureAction, createPublishBitbucketAction, createPublishBitbucketCloudAction, createPublishBitbucketServerAction, createPublishBitbucketServerPullRequestAction, createPublishGerritAction, createPublishGerritReviewAction, createPublishGithubAction, createPublishGithubPullRequestAction, createPublishGitlabAction, createPublishGitlabMergeRequestAction, createRouter, createTemplateAction, createWaitAction, scaffolderPlugin as default, executeShellCommand, fetchContents };
|
|
964
|
+
export { type ActionContext, type ActionPermissionRuleInput, type CreateBuiltInActionsOptions, type CreateGithubPullRequestActionOptions, type CreateWorkerOptions, type CurrentClaimedTask, DatabaseTaskStore, type DatabaseTaskStoreOptions, type RouterOptions, type RunCommandOptions, ScaffolderEntitiesProcessor, type SerializedTask, type SerializedTaskEvent, type TaskBroker, type TaskBrokerDispatchOptions, type TaskBrokerDispatchResult, type TaskCompletionState, type TaskContext, type TaskEventType, TaskManager, type TaskSecrets, type TaskStatus, type TaskStore, type TaskStoreCreateTaskOptions, type TaskStoreCreateTaskResult, type TaskStoreEmitOptions, type TaskStoreListEventsOptions, type TaskStoreRecoverTaskOptions, type TaskStoreShutDownTaskOptions, TaskWorker, type TemplateAction, TemplateActionRegistry, type TemplateFilter, type TemplateGlobal, type TemplatePermissionRuleInput, createBuiltinActions, createCatalogRegisterAction, createCatalogWriteAction, createDebugLogAction, createFetchCatalogEntityAction, createFetchPlainAction, createFetchPlainFileAction, createFetchTemplateAction, createFetchTemplateFileAction, createFilesystemDeleteAction, createFilesystemReadDirAction, createFilesystemRenameAction, createGithubActionsDispatchAction, createGithubDeployKeyAction, createGithubEnvironmentAction, createGithubIssuesLabelAction, createGithubRepoCreateAction, createGithubRepoPushAction, createGithubWebhookAction, createPublishAzureAction, createPublishBitbucketAction, createPublishBitbucketCloudAction, createPublishBitbucketServerAction, createPublishBitbucketServerPullRequestAction, createPublishGerritAction, createPublishGerritReviewAction, createPublishGithubAction, createPublishGithubPullRequestAction, createPublishGitlabAction, createPublishGitlabMergeRequestAction, createRouter, createTemplateAction, createWaitAction, scaffolderPlugin as default, executeShellCommand, fetchContents };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var pluginScaffolderNode = require('@backstage/plugin-scaffolder-node');
|
|
4
|
-
var
|
|
4
|
+
var z = require('zod');
|
|
5
5
|
var catalogModel = require('@backstage/catalog-model');
|
|
6
6
|
var fetch_examples = require('./fetch.examples.cjs.js');
|
|
7
7
|
|
|
@@ -14,25 +14,25 @@ function createFetchCatalogEntityAction(options) {
|
|
|
14
14
|
examples: fetch_examples.examples,
|
|
15
15
|
supportsDryRun: true,
|
|
16
16
|
schema: {
|
|
17
|
-
input:
|
|
18
|
-
entityRef:
|
|
17
|
+
input: z.z.object({
|
|
18
|
+
entityRef: z.z.string({
|
|
19
19
|
description: "Entity reference of the entity to get"
|
|
20
20
|
}).optional(),
|
|
21
|
-
entityRefs:
|
|
21
|
+
entityRefs: z.z.array(z.z.string(), {
|
|
22
22
|
description: "Entity references of the entities to get"
|
|
23
23
|
}).optional(),
|
|
24
|
-
optional:
|
|
24
|
+
optional: z.z.boolean({
|
|
25
25
|
description: "Allow the entity or entities to optionally exist. Default: false"
|
|
26
26
|
}).optional(),
|
|
27
|
-
defaultKind:
|
|
28
|
-
defaultNamespace:
|
|
27
|
+
defaultKind: z.z.string({ description: "The default kind" }).optional(),
|
|
28
|
+
defaultNamespace: z.z.string({ description: "The default namespace" }).optional()
|
|
29
29
|
}),
|
|
30
|
-
output:
|
|
31
|
-
entity:
|
|
30
|
+
output: z.z.object({
|
|
31
|
+
entity: z.z.any({
|
|
32
32
|
description: "Object containing same values used in the Entity schema. Only when used with `entityRef` parameter."
|
|
33
33
|
}).optional(),
|
|
34
|
-
entities:
|
|
35
|
-
|
|
34
|
+
entities: z.z.array(
|
|
35
|
+
z.z.any({
|
|
36
36
|
description: "Array containing objects with same values used in the Entity schema. Only when used with `entityRefs` parameter."
|
|
37
37
|
})
|
|
38
38
|
).optional()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.cjs.js","sources":["../../../../../src/scaffolder/actions/builtin/catalog/fetch.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 { CatalogApi } from '@backstage/catalog-client';\nimport { createTemplateAction } from '@backstage/plugin-scaffolder-node';\nimport { z } from 'zod';\nimport { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';\nimport { examples } from './fetch.examples';\nimport { AuthService } from '@backstage/backend-plugin-api';\n\nconst id = 'catalog:fetch';\n\n/**\n * Returns entity or entities from the catalog by entity reference(s).\n *\n * @public\n */\nexport function createFetchCatalogEntityAction(options: {\n catalogClient: CatalogApi;\n auth?: AuthService;\n}) {\n const { catalogClient, auth } = options;\n\n return createTemplateAction({\n id,\n description:\n 'Returns entity or entities from the catalog by entity reference(s)',\n examples,\n supportsDryRun: true,\n schema: {\n input: z.object({\n entityRef: z\n .string({\n description: 'Entity reference of the entity to get',\n })\n .optional(),\n entityRefs: z\n .array(z.string(), {\n description: 'Entity references of the entities to get',\n })\n .optional(),\n optional: z\n .boolean({\n description:\n 'Allow the entity or entities to optionally exist. Default: false',\n })\n .optional(),\n defaultKind: z.string({ description: 'The default kind' }).optional(),\n defaultNamespace: z\n .string({ description: 'The default namespace' })\n .optional(),\n }),\n output: z.object({\n entity: z\n .any({\n description:\n 'Object containing same values used in the Entity schema. Only when used with `entityRef` parameter.',\n })\n .optional(),\n entities: z\n .array(\n z.any({\n description:\n 'Array containing objects with same values used in the Entity schema. Only when used with `entityRefs` parameter.',\n }),\n )\n .optional(),\n }),\n },\n async handler(ctx) {\n const { entityRef, entityRefs, optional, defaultKind, defaultNamespace } =\n ctx.input;\n if (!entityRef && !entityRefs) {\n if (optional) {\n return;\n }\n throw new Error('Missing entity reference or references');\n }\n\n const { token } = (await auth?.getPluginRequestToken({\n onBehalfOf: await ctx.getInitiatorCredentials(),\n targetPluginId: 'catalog',\n })) ?? { token: ctx.secrets?.backstageToken };\n\n if (entityRef) {\n const entity = await catalogClient.getEntityByRef(\n stringifyEntityRef(\n parseEntityRef(entityRef, { defaultKind, defaultNamespace }),\n ),\n {\n token,\n },\n );\n\n if (!entity && !optional) {\n throw new Error(`Entity ${entityRef} not found`);\n }\n ctx.output('entity', entity ?? null);\n }\n\n if (entityRefs) {\n const entities = await catalogClient.getEntitiesByRefs(\n {\n entityRefs: entityRefs.map(ref =>\n stringifyEntityRef(\n parseEntityRef(ref, { defaultKind, defaultNamespace }),\n ),\n ),\n },\n {\n token,\n },\n );\n\n const finalEntities = entities.items.map((e, i) => {\n if (!e && !optional) {\n throw new Error(`Entity ${entityRefs[i]} not found`);\n }\n return e ?? null;\n });\n\n ctx.output('entities', finalEntities);\n }\n },\n });\n}\n"],"names":["createTemplateAction","examples","z","stringifyEntityRef","parseEntityRef"],"mappings":";;;;;;;AAuBA,MAAM,EAAK,GAAA,eAAA;AAOJ,SAAS,+BAA+B,OAG5C,EAAA;AACD,EAAM,MAAA,EAAE,aAAe,EAAA,IAAA,EAAS,GAAA,OAAA;AAEhC,EAAA,OAAOA,yCAAqB,CAAA;AAAA,IAC1B,EAAA;AAAA,IACA,WACE,EAAA,oEAAA;AAAA,cACFC,uBAAA;AAAA,IACA,cAAgB,EAAA,IAAA;AAAA,IAChB,MAAQ,EAAA;AAAA,MACN,KAAA,EAAOC,
|
|
1
|
+
{"version":3,"file":"fetch.cjs.js","sources":["../../../../../src/scaffolder/actions/builtin/catalog/fetch.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 { CatalogApi } from '@backstage/catalog-client';\nimport { createTemplateAction } from '@backstage/plugin-scaffolder-node';\nimport { z } from 'zod';\nimport { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model';\nimport { examples } from './fetch.examples';\nimport { AuthService } from '@backstage/backend-plugin-api';\n\nconst id = 'catalog:fetch';\n\n/**\n * Returns entity or entities from the catalog by entity reference(s).\n *\n * @public\n */\nexport function createFetchCatalogEntityAction(options: {\n catalogClient: CatalogApi;\n auth?: AuthService;\n}) {\n const { catalogClient, auth } = options;\n\n return createTemplateAction({\n id,\n description:\n 'Returns entity or entities from the catalog by entity reference(s)',\n examples,\n supportsDryRun: true,\n schema: {\n input: z.object({\n entityRef: z\n .string({\n description: 'Entity reference of the entity to get',\n })\n .optional(),\n entityRefs: z\n .array(z.string(), {\n description: 'Entity references of the entities to get',\n })\n .optional(),\n optional: z\n .boolean({\n description:\n 'Allow the entity or entities to optionally exist. Default: false',\n })\n .optional(),\n defaultKind: z.string({ description: 'The default kind' }).optional(),\n defaultNamespace: z\n .string({ description: 'The default namespace' })\n .optional(),\n }),\n output: z.object({\n entity: z\n .any({\n description:\n 'Object containing same values used in the Entity schema. Only when used with `entityRef` parameter.',\n })\n .optional(),\n entities: z\n .array(\n z.any({\n description:\n 'Array containing objects with same values used in the Entity schema. Only when used with `entityRefs` parameter.',\n }),\n )\n .optional(),\n }),\n },\n async handler(ctx) {\n const { entityRef, entityRefs, optional, defaultKind, defaultNamespace } =\n ctx.input;\n if (!entityRef && !entityRefs) {\n if (optional) {\n return;\n }\n throw new Error('Missing entity reference or references');\n }\n\n const { token } = (await auth?.getPluginRequestToken({\n onBehalfOf: await ctx.getInitiatorCredentials(),\n targetPluginId: 'catalog',\n })) ?? { token: ctx.secrets?.backstageToken };\n\n if (entityRef) {\n const entity = await catalogClient.getEntityByRef(\n stringifyEntityRef(\n parseEntityRef(entityRef, { defaultKind, defaultNamespace }),\n ),\n {\n token,\n },\n );\n\n if (!entity && !optional) {\n throw new Error(`Entity ${entityRef} not found`);\n }\n ctx.output('entity', entity ?? null);\n }\n\n if (entityRefs) {\n const entities = await catalogClient.getEntitiesByRefs(\n {\n entityRefs: entityRefs.map(ref =>\n stringifyEntityRef(\n parseEntityRef(ref, { defaultKind, defaultNamespace }),\n ),\n ),\n },\n {\n token,\n },\n );\n\n const finalEntities = entities.items.map((e, i) => {\n if (!e && !optional) {\n throw new Error(`Entity ${entityRefs[i]} not found`);\n }\n return e ?? null;\n });\n\n ctx.output('entities', finalEntities);\n }\n },\n });\n}\n"],"names":["createTemplateAction","examples","z","stringifyEntityRef","parseEntityRef"],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ var fs = require('fs-extra');
|
|
|
4
4
|
var pluginScaffolderNode = require('@backstage/plugin-scaffolder-node');
|
|
5
5
|
var yaml = require('yaml');
|
|
6
6
|
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
7
|
-
var
|
|
7
|
+
var z = require('zod');
|
|
8
8
|
var write_examples = require('./write.examples.cjs.js');
|
|
9
9
|
|
|
10
10
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
@@ -36,10 +36,10 @@ function createCatalogWriteAction() {
|
|
|
36
36
|
id,
|
|
37
37
|
description: "Writes the catalog-info.yaml for your template",
|
|
38
38
|
schema: {
|
|
39
|
-
input:
|
|
40
|
-
filePath:
|
|
39
|
+
input: z.z.object({
|
|
40
|
+
filePath: z.z.string().optional().describe("Defaults to catalog-info.yaml"),
|
|
41
41
|
// TODO: this should reference an zod entity validator if it existed.
|
|
42
|
-
entity:
|
|
42
|
+
entity: z.z.record(z.z.any()).describe(
|
|
43
43
|
"You can provide the same values used in the Entity schema."
|
|
44
44
|
)
|
|
45
45
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"write.cjs.js","sources":["../../../../../src/scaffolder/actions/builtin/catalog/write.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 fs from 'fs-extra';\nimport { createTemplateAction } from '@backstage/plugin-scaffolder-node';\nimport * as yaml from 'yaml';\nimport { resolveSafeChildPath } from '@backstage/backend-plugin-api';\nimport { z } from 'zod';\nimport { examples } from './write.examples';\n\nconst id = 'catalog:write';\n\n/**\n * Writes a catalog descriptor file containing the provided entity to a path in the workspace.\n * @public\n */\n\nexport function createCatalogWriteAction() {\n return createTemplateAction({\n id,\n description: 'Writes the catalog-info.yaml for your template',\n schema: {\n input: z.object({\n filePath: z\n .string()\n .optional()\n .describe('Defaults to catalog-info.yaml'),\n // TODO: this should reference an zod entity validator if it existed.\n entity: z\n .record(z.any())\n .describe(\n 'You can provide the same values used in the Entity schema.',\n ),\n }),\n },\n examples,\n supportsDryRun: true,\n async handler(ctx) {\n const { filePath, entity } = ctx.input;\n const entityRef = ctx.templateInfo?.entityRef;\n const path = filePath ?? 'catalog-info.yaml';\n ctx.logger.info(`Writing ${path}`);\n\n await fs.outputFile(\n resolveSafeChildPath(ctx.workspacePath, path),\n yaml.stringify({\n ...entity,\n metadata: {\n ...entity.metadata,\n ...(entityRef\n ? {\n annotations: {\n ...entity.metadata.annotations,\n 'backstage.io/source-template': entityRef,\n },\n }\n : undefined),\n },\n }),\n );\n },\n });\n}\n"],"names":["createTemplateAction","z","examples","fs","resolveSafeChildPath","yaml"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAM,EAAK,GAAA,eAAA;AAOJ,SAAS,wBAA2B,GAAA;AACzC,EAAA,OAAOA,yCAAqB,CAAA;AAAA,IAC1B,EAAA;AAAA,IACA,WAAa,EAAA,gDAAA;AAAA,IACb,MAAQ,EAAA;AAAA,MACN,KAAA,EAAOC,
|
|
1
|
+
{"version":3,"file":"write.cjs.js","sources":["../../../../../src/scaffolder/actions/builtin/catalog/write.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 fs from 'fs-extra';\nimport { createTemplateAction } from '@backstage/plugin-scaffolder-node';\nimport * as yaml from 'yaml';\nimport { resolveSafeChildPath } from '@backstage/backend-plugin-api';\nimport { z } from 'zod';\nimport { examples } from './write.examples';\n\nconst id = 'catalog:write';\n\n/**\n * Writes a catalog descriptor file containing the provided entity to a path in the workspace.\n * @public\n */\n\nexport function createCatalogWriteAction() {\n return createTemplateAction({\n id,\n description: 'Writes the catalog-info.yaml for your template',\n schema: {\n input: z.object({\n filePath: z\n .string()\n .optional()\n .describe('Defaults to catalog-info.yaml'),\n // TODO: this should reference an zod entity validator if it existed.\n entity: z\n .record(z.any())\n .describe(\n 'You can provide the same values used in the Entity schema.',\n ),\n }),\n },\n examples,\n supportsDryRun: true,\n async handler(ctx) {\n const { filePath, entity } = ctx.input;\n const entityRef = ctx.templateInfo?.entityRef;\n const path = filePath ?? 'catalog-info.yaml';\n ctx.logger.info(`Writing ${path}`);\n\n await fs.outputFile(\n resolveSafeChildPath(ctx.workspacePath, path),\n yaml.stringify({\n ...entity,\n metadata: {\n ...entity.metadata,\n ...(entityRef\n ? {\n annotations: {\n ...entity.metadata.annotations,\n 'backstage.io/source-template': entityRef,\n },\n }\n : undefined),\n },\n }),\n );\n },\n });\n}\n"],"names":["createTemplateAction","z","examples","fs","resolveSafeChildPath","yaml"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuBA,MAAM,EAAK,GAAA,eAAA;AAOJ,SAAS,wBAA2B,GAAA;AACzC,EAAA,OAAOA,yCAAqB,CAAA;AAAA,IAC1B,EAAA;AAAA,IACA,WAAa,EAAA,gDAAA;AAAA,IACb,MAAQ,EAAA;AAAA,MACN,KAAA,EAAOC,IAAE,MAAO,CAAA;AAAA,QACd,UAAUA,GACP,CAAA,MAAA,GACA,QAAS,EAAA,CACT,SAAS,+BAA+B,CAAA;AAAA;AAAA,QAE3C,QAAQA,GACL,CAAA,MAAA,CAAOA,GAAE,CAAA,GAAA,EAAK,CACd,CAAA,QAAA;AAAA,UACC;AAAA;AACF,OACH;AAAA,KACH;AAAA,cACAC,uBAAA;AAAA,IACA,cAAgB,EAAA,IAAA;AAAA,IAChB,MAAM,QAAQ,GAAK,EAAA;AACjB,MAAA,MAAM,EAAE,QAAA,EAAU,MAAO,EAAA,GAAI,GAAI,CAAA,KAAA;AACjC,MAAM,MAAA,SAAA,GAAY,IAAI,YAAc,EAAA,SAAA;AACpC,MAAA,MAAM,OAAO,QAAY,IAAA,mBAAA;AACzB,MAAA,GAAA,CAAI,MAAO,CAAA,IAAA,CAAK,CAAW,QAAA,EAAA,IAAI,CAAE,CAAA,CAAA;AAEjC,MAAA,MAAMC,mBAAG,CAAA,UAAA;AAAA,QACPC,qCAAA,CAAqB,GAAI,CAAA,aAAA,EAAe,IAAI,CAAA;AAAA,QAC5CC,gBAAK,SAAU,CAAA;AAAA,UACb,GAAG,MAAA;AAAA,UACH,QAAU,EAAA;AAAA,YACR,GAAG,MAAO,CAAA,QAAA;AAAA,YACV,GAAI,SACA,GAAA;AAAA,cACE,WAAa,EAAA;AAAA,gBACX,GAAG,OAAO,QAAS,CAAA,WAAA;AAAA,gBACnB,8BAAgC,EAAA;AAAA;AAClC,aAEF,GAAA,KAAA;AAAA;AACN,SACD;AAAA,OACH;AAAA;AACF,GACD,CAAA;AACH;;;;"}
|
|
@@ -12,6 +12,7 @@ var template = require('./fetch/template.cjs.js');
|
|
|
12
12
|
var templateFile = require('./fetch/templateFile.cjs.js');
|
|
13
13
|
var _delete = require('./filesystem/delete.cjs.js');
|
|
14
14
|
var rename = require('./filesystem/rename.cjs.js');
|
|
15
|
+
var read = require('./filesystem/read.cjs.js');
|
|
15
16
|
var github = require('@backstage/plugin-scaffolder-backend-module-github');
|
|
16
17
|
var azure = require('@backstage/plugin-scaffolder-backend-module-azure');
|
|
17
18
|
var bitbucket = require('@backstage/plugin-scaffolder-backend-module-bitbucket');
|
|
@@ -112,6 +113,7 @@ const createBuiltinActions = (options) => {
|
|
|
112
113
|
fetch.createFetchCatalogEntityAction({ catalogClient, auth }),
|
|
113
114
|
write.createCatalogWriteAction(),
|
|
114
115
|
_delete.createFilesystemDeleteAction(),
|
|
116
|
+
read.createFilesystemReadDirAction(),
|
|
115
117
|
rename.createFilesystemRenameAction(),
|
|
116
118
|
github.createGithubActionsDispatchAction({
|
|
117
119
|
integrations,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createBuiltinActions.cjs.js","sources":["../../../../src/scaffolder/actions/builtin/createBuiltinActions.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 { CatalogApi } from '@backstage/catalog-client';\nimport { Config } from '@backstage/config';\nimport {\n DefaultGithubCredentialsProvider,\n GithubCredentialsProvider,\n ScmIntegrations,\n} from '@backstage/integration';\nimport {\n TemplateAction,\n TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport {\n createCatalogRegisterAction,\n createCatalogWriteAction,\n createFetchCatalogEntityAction,\n} from './catalog';\n\nimport { createDebugLogAction, createWaitAction } from './debug';\nimport {\n createFetchPlainAction,\n createFetchPlainFileAction,\n createFetchTemplateAction,\n createFetchTemplateFileAction,\n} from './fetch';\nimport {\n createFilesystemDeleteAction,\n createFilesystemRenameAction,\n} from './filesystem';\nimport {\n createGithubActionsDispatchAction,\n createGithubAutolinksAction,\n createGithubDeployKeyAction,\n createGithubEnvironmentAction,\n createGithubIssuesLabelAction,\n createGithubRepoCreateAction,\n createGithubRepoPushAction,\n createGithubWebhookAction,\n createPublishGithubAction,\n createPublishGithubPullRequestAction,\n} from '@backstage/plugin-scaffolder-backend-module-github';\n\nimport { createPublishAzureAction } from '@backstage/plugin-scaffolder-backend-module-azure';\n\nimport { createPublishBitbucketAction } from '@backstage/plugin-scaffolder-backend-module-bitbucket';\n\nimport {\n createPublishBitbucketCloudAction,\n createBitbucketPipelinesRunAction,\n createPublishBitbucketCloudPullRequestAction,\n} from '@backstage/plugin-scaffolder-backend-module-bitbucket-cloud';\n\nimport {\n createPublishBitbucketServerAction,\n createPublishBitbucketServerPullRequestAction,\n} from '@backstage/plugin-scaffolder-backend-module-bitbucket-server';\n\nimport {\n createPublishGerritAction,\n createPublishGerritReviewAction,\n} from '@backstage/plugin-scaffolder-backend-module-gerrit';\n\nimport {\n createPublishGitlabAction,\n createGitlabRepoPushAction,\n createPublishGitlabMergeRequestAction,\n} from '@backstage/plugin-scaffolder-backend-module-gitlab';\n\nimport { createPublishGiteaAction } from '@backstage/plugin-scaffolder-backend-module-gitea';\nimport { AuthService, UrlReaderService } from '@backstage/backend-plugin-api';\n\n/**\n * The options passed to {@link createBuiltinActions}\n * @public\n */\nexport interface CreateBuiltInActionsOptions {\n /**\n * The {@link @backstage/backend-plugin-api#UrlReaderService} interface that will be used in the default actions.\n */\n reader: UrlReaderService;\n /**\n * The {@link @backstage/integrations#ScmIntegrations} that will be used in the default actions.\n */\n integrations: ScmIntegrations;\n /**\n * The {@link @backstage/catalog-client#CatalogApi} that will be used in the default actions.\n */\n catalogClient: CatalogApi;\n /**\n * The {@link @backstage/backend-plugin-api#AuthService} that will be used in the default actions.\n */\n auth?: AuthService;\n /**\n * The {@link @backstage/config#Config} that will be used in the default actions.\n */\n config: Config;\n /**\n * Additional custom filters that will be passed to the nunjucks template engine for use in\n * Template Manifests and also template skeleton files when using `fetch:template`.\n */\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n additionalTemplateGlobals?: Record<string, TemplateGlobal>;\n}\n\n/**\n * A function to generate create a list of default actions that the scaffolder provides.\n * Is called internally in the default setup, but can be used when adding your own actions or overriding the default ones\n *\n * TODO(blam): version 2 of the scaffolder shouldn't ship with the additional modules. We should ship the basics, and let people install\n * modules for the providers they want to use.\n * @public\n * @returns A list of actions that can be used in the scaffolder\n *\n */\nexport const createBuiltinActions = (\n options: CreateBuiltInActionsOptions,\n): TemplateAction[] => {\n const {\n reader,\n integrations,\n catalogClient,\n auth,\n config,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n } = options;\n\n const githubCredentialsProvider: GithubCredentialsProvider =\n DefaultGithubCredentialsProvider.fromIntegrations(integrations);\n\n const actions = [\n createFetchPlainAction({\n reader,\n integrations,\n }),\n createFetchPlainFileAction({\n reader,\n integrations,\n }),\n createFetchTemplateAction({\n integrations,\n reader,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n }),\n createFetchTemplateFileAction({\n integrations,\n reader,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n }),\n createPublishGerritAction({\n integrations,\n config,\n }),\n createPublishGerritReviewAction({\n integrations,\n config,\n }),\n createPublishGiteaAction({\n integrations,\n config,\n }),\n createPublishGithubAction({\n integrations,\n config,\n githubCredentialsProvider,\n }),\n createPublishGithubPullRequestAction({\n integrations,\n githubCredentialsProvider,\n config,\n }),\n createPublishGitlabAction({\n integrations,\n config,\n }),\n createPublishGitlabMergeRequestAction({\n integrations,\n }),\n createGitlabRepoPushAction({\n integrations,\n }),\n createPublishBitbucketAction({\n integrations,\n config,\n }),\n createPublishBitbucketCloudAction({\n integrations,\n config,\n }),\n createPublishBitbucketCloudPullRequestAction({ integrations, config }),\n createPublishBitbucketServerAction({\n integrations,\n config,\n }),\n createPublishBitbucketServerPullRequestAction({\n integrations,\n config,\n }),\n createPublishAzureAction({\n integrations,\n config,\n }),\n createDebugLogAction(),\n createWaitAction(),\n createCatalogRegisterAction({ catalogClient, integrations, auth }),\n createFetchCatalogEntityAction({ catalogClient, auth }),\n createCatalogWriteAction(),\n createFilesystemDeleteAction(),\n createFilesystemRenameAction(),\n createGithubActionsDispatchAction({\n integrations,\n githubCredentialsProvider,\n }),\n createGithubWebhookAction({\n integrations,\n githubCredentialsProvider,\n }),\n createGithubIssuesLabelAction({\n integrations,\n githubCredentialsProvider,\n }),\n createGithubRepoCreateAction({\n integrations,\n githubCredentialsProvider,\n }),\n createGithubRepoPushAction({\n integrations,\n config,\n githubCredentialsProvider,\n }),\n createGithubEnvironmentAction({\n integrations,\n catalogClient,\n }),\n createGithubDeployKeyAction({\n integrations,\n }),\n createGithubAutolinksAction({\n integrations,\n githubCredentialsProvider,\n }),\n createBitbucketPipelinesRunAction({\n integrations,\n }),\n ];\n\n return actions as TemplateAction[];\n};\n"],"names":["DefaultGithubCredentialsProvider","createFetchPlainAction","createFetchPlainFileAction","createFetchTemplateAction","createFetchTemplateFileAction","createPublishGerritAction","createPublishGerritReviewAction","createPublishGiteaAction","createPublishGithubAction","createPublishGithubPullRequestAction","createPublishGitlabAction","createPublishGitlabMergeRequestAction","createGitlabRepoPushAction","createPublishBitbucketAction","createPublishBitbucketCloudAction","createPublishBitbucketCloudPullRequestAction","createPublishBitbucketServerAction","createPublishBitbucketServerPullRequestAction","createPublishAzureAction","createDebugLogAction","createWaitAction","createCatalogRegisterAction","createFetchCatalogEntityAction","createCatalogWriteAction","createFilesystemDeleteAction","createFilesystemRenameAction","createGithubActionsDispatchAction","createGithubWebhookAction","createGithubIssuesLabelAction","createGithubRepoCreateAction","createGithubRepoPushAction","createGithubEnvironmentAction","createGithubDeployKeyAction","createGithubAutolinksAction","createBitbucketPipelinesRunAction"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"createBuiltinActions.cjs.js","sources":["../../../../src/scaffolder/actions/builtin/createBuiltinActions.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 { CatalogApi } from '@backstage/catalog-client';\nimport { Config } from '@backstage/config';\nimport {\n DefaultGithubCredentialsProvider,\n GithubCredentialsProvider,\n ScmIntegrations,\n} from '@backstage/integration';\nimport {\n TemplateAction,\n TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport {\n createCatalogRegisterAction,\n createCatalogWriteAction,\n createFetchCatalogEntityAction,\n} from './catalog';\n\nimport { createDebugLogAction, createWaitAction } from './debug';\nimport {\n createFetchPlainAction,\n createFetchPlainFileAction,\n createFetchTemplateAction,\n createFetchTemplateFileAction,\n} from './fetch';\nimport {\n createFilesystemDeleteAction,\n createFilesystemReadDirAction,\n createFilesystemRenameAction,\n} from './filesystem';\nimport {\n createGithubActionsDispatchAction,\n createGithubAutolinksAction,\n createGithubDeployKeyAction,\n createGithubEnvironmentAction,\n createGithubIssuesLabelAction,\n createGithubRepoCreateAction,\n createGithubRepoPushAction,\n createGithubWebhookAction,\n createPublishGithubAction,\n createPublishGithubPullRequestAction,\n} from '@backstage/plugin-scaffolder-backend-module-github';\n\nimport { createPublishAzureAction } from '@backstage/plugin-scaffolder-backend-module-azure';\n\nimport { createPublishBitbucketAction } from '@backstage/plugin-scaffolder-backend-module-bitbucket';\n\nimport {\n createPublishBitbucketCloudAction,\n createBitbucketPipelinesRunAction,\n createPublishBitbucketCloudPullRequestAction,\n} from '@backstage/plugin-scaffolder-backend-module-bitbucket-cloud';\n\nimport {\n createPublishBitbucketServerAction,\n createPublishBitbucketServerPullRequestAction,\n} from '@backstage/plugin-scaffolder-backend-module-bitbucket-server';\n\nimport {\n createPublishGerritAction,\n createPublishGerritReviewAction,\n} from '@backstage/plugin-scaffolder-backend-module-gerrit';\n\nimport {\n createPublishGitlabAction,\n createGitlabRepoPushAction,\n createPublishGitlabMergeRequestAction,\n} from '@backstage/plugin-scaffolder-backend-module-gitlab';\n\nimport { createPublishGiteaAction } from '@backstage/plugin-scaffolder-backend-module-gitea';\nimport { AuthService, UrlReaderService } from '@backstage/backend-plugin-api';\n\n/**\n * The options passed to {@link createBuiltinActions}\n * @public\n */\nexport interface CreateBuiltInActionsOptions {\n /**\n * The {@link @backstage/backend-plugin-api#UrlReaderService} interface that will be used in the default actions.\n */\n reader: UrlReaderService;\n /**\n * The {@link @backstage/integrations#ScmIntegrations} that will be used in the default actions.\n */\n integrations: ScmIntegrations;\n /**\n * The {@link @backstage/catalog-client#CatalogApi} that will be used in the default actions.\n */\n catalogClient: CatalogApi;\n /**\n * The {@link @backstage/backend-plugin-api#AuthService} that will be used in the default actions.\n */\n auth?: AuthService;\n /**\n * The {@link @backstage/config#Config} that will be used in the default actions.\n */\n config: Config;\n /**\n * Additional custom filters that will be passed to the nunjucks template engine for use in\n * Template Manifests and also template skeleton files when using `fetch:template`.\n */\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n additionalTemplateGlobals?: Record<string, TemplateGlobal>;\n}\n\n/**\n * A function to generate create a list of default actions that the scaffolder provides.\n * Is called internally in the default setup, but can be used when adding your own actions or overriding the default ones\n *\n * TODO(blam): version 2 of the scaffolder shouldn't ship with the additional modules. We should ship the basics, and let people install\n * modules for the providers they want to use.\n * @public\n * @returns A list of actions that can be used in the scaffolder\n *\n */\nexport const createBuiltinActions = (\n options: CreateBuiltInActionsOptions,\n): TemplateAction[] => {\n const {\n reader,\n integrations,\n catalogClient,\n auth,\n config,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n } = options;\n\n const githubCredentialsProvider: GithubCredentialsProvider =\n DefaultGithubCredentialsProvider.fromIntegrations(integrations);\n\n const actions = [\n createFetchPlainAction({\n reader,\n integrations,\n }),\n createFetchPlainFileAction({\n reader,\n integrations,\n }),\n createFetchTemplateAction({\n integrations,\n reader,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n }),\n createFetchTemplateFileAction({\n integrations,\n reader,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n }),\n createPublishGerritAction({\n integrations,\n config,\n }),\n createPublishGerritReviewAction({\n integrations,\n config,\n }),\n createPublishGiteaAction({\n integrations,\n config,\n }),\n createPublishGithubAction({\n integrations,\n config,\n githubCredentialsProvider,\n }),\n createPublishGithubPullRequestAction({\n integrations,\n githubCredentialsProvider,\n config,\n }),\n createPublishGitlabAction({\n integrations,\n config,\n }),\n createPublishGitlabMergeRequestAction({\n integrations,\n }),\n createGitlabRepoPushAction({\n integrations,\n }),\n createPublishBitbucketAction({\n integrations,\n config,\n }),\n createPublishBitbucketCloudAction({\n integrations,\n config,\n }),\n createPublishBitbucketCloudPullRequestAction({ integrations, config }),\n createPublishBitbucketServerAction({\n integrations,\n config,\n }),\n createPublishBitbucketServerPullRequestAction({\n integrations,\n config,\n }),\n createPublishAzureAction({\n integrations,\n config,\n }),\n createDebugLogAction(),\n createWaitAction(),\n createCatalogRegisterAction({ catalogClient, integrations, auth }),\n createFetchCatalogEntityAction({ catalogClient, auth }),\n createCatalogWriteAction(),\n createFilesystemDeleteAction(),\n createFilesystemReadDirAction(),\n createFilesystemRenameAction(),\n createGithubActionsDispatchAction({\n integrations,\n githubCredentialsProvider,\n }),\n createGithubWebhookAction({\n integrations,\n githubCredentialsProvider,\n }),\n createGithubIssuesLabelAction({\n integrations,\n githubCredentialsProvider,\n }),\n createGithubRepoCreateAction({\n integrations,\n githubCredentialsProvider,\n }),\n createGithubRepoPushAction({\n integrations,\n config,\n githubCredentialsProvider,\n }),\n createGithubEnvironmentAction({\n integrations,\n catalogClient,\n }),\n createGithubDeployKeyAction({\n integrations,\n }),\n createGithubAutolinksAction({\n integrations,\n githubCredentialsProvider,\n }),\n createBitbucketPipelinesRunAction({\n integrations,\n }),\n ];\n\n return actions as TemplateAction[];\n};\n"],"names":["DefaultGithubCredentialsProvider","createFetchPlainAction","createFetchPlainFileAction","createFetchTemplateAction","createFetchTemplateFileAction","createPublishGerritAction","createPublishGerritReviewAction","createPublishGiteaAction","createPublishGithubAction","createPublishGithubPullRequestAction","createPublishGitlabAction","createPublishGitlabMergeRequestAction","createGitlabRepoPushAction","createPublishBitbucketAction","createPublishBitbucketCloudAction","createPublishBitbucketCloudPullRequestAction","createPublishBitbucketServerAction","createPublishBitbucketServerPullRequestAction","createPublishAzureAction","createDebugLogAction","createWaitAction","createCatalogRegisterAction","createFetchCatalogEntityAction","createCatalogWriteAction","createFilesystemDeleteAction","createFilesystemReadDirAction","createFilesystemRenameAction","createGithubActionsDispatchAction","createGithubWebhookAction","createGithubIssuesLabelAction","createGithubRepoCreateAction","createGithubRepoPushAction","createGithubEnvironmentAction","createGithubDeployKeyAction","createGithubAutolinksAction","createBitbucketPipelinesRunAction"],"mappings":"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"}
|
|
@@ -5,7 +5,7 @@ var path = require('path');
|
|
|
5
5
|
var pluginScaffolderNode = require('@backstage/plugin-scaffolder-node');
|
|
6
6
|
var log_examples = require('./log.examples.cjs.js');
|
|
7
7
|
var fs = require('fs');
|
|
8
|
-
var
|
|
8
|
+
var z = require('zod');
|
|
9
9
|
|
|
10
10
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
11
11
|
|
|
@@ -18,9 +18,9 @@ function createDebugLogAction() {
|
|
|
18
18
|
description: "Writes a message into the log and/or lists all files in the workspace.",
|
|
19
19
|
examples: log_examples.examples,
|
|
20
20
|
schema: {
|
|
21
|
-
input:
|
|
22
|
-
message:
|
|
23
|
-
listWorkspace:
|
|
21
|
+
input: z.z.object({
|
|
22
|
+
message: z.z.string({ description: "Message to output." }).optional(),
|
|
23
|
+
listWorkspace: z.z.union([z.z.boolean(), z.z.enum(["with-filenames", "with-contents"])], {
|
|
24
24
|
description: 'List all files in the workspace. If used with "with-contents", also the file contents are listed.'
|
|
25
25
|
}).optional()
|
|
26
26
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log.cjs.js","sources":["../../../../../src/scaffolder/actions/builtin/debug/log.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 { readdir, stat } from 'fs-extra';\nimport { join, relative } from 'path';\nimport { createTemplateAction } from '@backstage/plugin-scaffolder-node';\nimport { examples } from './log.examples';\nimport fs from 'fs';\nimport { z } from 'zod';\n\nconst id = 'debug:log';\n\n/**\n * Writes a message into the log or lists all files in the workspace\n *\n * @remarks\n *\n * This task is useful for local development and testing of both the scaffolder\n * and scaffolder templates.\n *\n * @public\n */\nexport function createDebugLogAction() {\n return createTemplateAction<{\n message?: string;\n listWorkspace?: boolean | 'with-filenames' | 'with-contents';\n }>({\n id,\n description:\n 'Writes a message into the log and/or lists all files in the workspace.',\n examples,\n schema: {\n input: z.object({\n message: z.string({ description: 'Message to output.' }).optional(),\n listWorkspace: z\n .union([z.boolean(), z.enum(['with-filenames', 'with-contents'])], {\n description:\n 'List all files in the workspace. If used with \"with-contents\", also the file contents are listed.',\n })\n .optional(),\n }),\n },\n supportsDryRun: true,\n async handler(ctx) {\n ctx.logger.info(JSON.stringify(ctx.input, null, 2));\n\n if (ctx.input?.message) {\n ctx.logger.info(ctx.input.message);\n }\n\n if (ctx.input?.listWorkspace) {\n const files = await recursiveReadDir(ctx.workspacePath);\n ctx.logger.info(\n `Workspace:\\n${files\n .map(f => {\n const relativePath = relative(ctx.workspacePath, f);\n if (ctx.input?.listWorkspace === 'with-contents') {\n const content = fs.readFileSync(f, 'utf-8');\n return ` - ${relativePath}:\\n\\n ${content}`;\n }\n return ` - ${relativePath}`;\n })\n .join('\\n')}`,\n );\n }\n },\n });\n}\n\nexport async function recursiveReadDir(dir: string): Promise<string[]> {\n const subdirs = await readdir(dir);\n const files = await Promise.all(\n subdirs.map(async subdir => {\n const res = join(dir, subdir);\n return (await stat(res)).isDirectory() ? recursiveReadDir(res) : [res];\n }),\n );\n return files.reduce((a, f) => a.concat(f), []);\n}\n"],"names":["createTemplateAction","examples","z","relative","fs","readdir","join","stat"],"mappings":";;;;;;;;;;;;;AAuBA,MAAM,EAAK,GAAA,WAAA;AAYJ,SAAS,oBAAuB,GAAA;AACrC,EAAA,OAAOA,yCAGJ,CAAA;AAAA,IACD,EAAA;AAAA,IACA,WACE,EAAA,wEAAA;AAAA,cACFC,qBAAA;AAAA,IACA,MAAQ,EAAA;AAAA,MACN,KAAA,EAAOC,
|
|
1
|
+
{"version":3,"file":"log.cjs.js","sources":["../../../../../src/scaffolder/actions/builtin/debug/log.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 { readdir, stat } from 'fs-extra';\nimport { join, relative } from 'path';\nimport { createTemplateAction } from '@backstage/plugin-scaffolder-node';\nimport { examples } from './log.examples';\nimport fs from 'fs';\nimport { z } from 'zod';\n\nconst id = 'debug:log';\n\n/**\n * Writes a message into the log or lists all files in the workspace\n *\n * @remarks\n *\n * This task is useful for local development and testing of both the scaffolder\n * and scaffolder templates.\n *\n * @public\n */\nexport function createDebugLogAction() {\n return createTemplateAction<{\n message?: string;\n listWorkspace?: boolean | 'with-filenames' | 'with-contents';\n }>({\n id,\n description:\n 'Writes a message into the log and/or lists all files in the workspace.',\n examples,\n schema: {\n input: z.object({\n message: z.string({ description: 'Message to output.' }).optional(),\n listWorkspace: z\n .union([z.boolean(), z.enum(['with-filenames', 'with-contents'])], {\n description:\n 'List all files in the workspace. If used with \"with-contents\", also the file contents are listed.',\n })\n .optional(),\n }),\n },\n supportsDryRun: true,\n async handler(ctx) {\n ctx.logger.info(JSON.stringify(ctx.input, null, 2));\n\n if (ctx.input?.message) {\n ctx.logger.info(ctx.input.message);\n }\n\n if (ctx.input?.listWorkspace) {\n const files = await recursiveReadDir(ctx.workspacePath);\n ctx.logger.info(\n `Workspace:\\n${files\n .map(f => {\n const relativePath = relative(ctx.workspacePath, f);\n if (ctx.input?.listWorkspace === 'with-contents') {\n const content = fs.readFileSync(f, 'utf-8');\n return ` - ${relativePath}:\\n\\n ${content}`;\n }\n return ` - ${relativePath}`;\n })\n .join('\\n')}`,\n );\n }\n },\n });\n}\n\nexport async function recursiveReadDir(dir: string): Promise<string[]> {\n const subdirs = await readdir(dir);\n const files = await Promise.all(\n subdirs.map(async subdir => {\n const res = join(dir, subdir);\n return (await stat(res)).isDirectory() ? recursiveReadDir(res) : [res];\n }),\n );\n return files.reduce((a, f) => a.concat(f), []);\n}\n"],"names":["createTemplateAction","examples","z","relative","fs","readdir","join","stat"],"mappings":";;;;;;;;;;;;;AAuBA,MAAM,EAAK,GAAA,WAAA;AAYJ,SAAS,oBAAuB,GAAA;AACrC,EAAA,OAAOA,yCAGJ,CAAA;AAAA,IACD,EAAA;AAAA,IACA,WACE,EAAA,wEAAA;AAAA,cACFC,qBAAA;AAAA,IACA,MAAQ,EAAA;AAAA,MACN,KAAA,EAAOC,IAAE,MAAO,CAAA;AAAA,QACd,OAAA,EAASA,IAAE,MAAO,CAAA,EAAE,aAAa,oBAAqB,EAAC,EAAE,QAAS,EAAA;AAAA,QAClE,aAAe,EAAAA,GAAA,CACZ,KAAM,CAAA,CAACA,IAAE,OAAQ,EAAA,EAAGA,GAAE,CAAA,IAAA,CAAK,CAAC,gBAAA,EAAkB,eAAe,CAAC,CAAC,CAAG,EAAA;AAAA,UACjE,WACE,EAAA;AAAA,SACH,EACA,QAAS;AAAA,OACb;AAAA,KACH;AAAA,IACA,cAAgB,EAAA,IAAA;AAAA,IAChB,MAAM,QAAQ,GAAK,EAAA;AACjB,MAAI,GAAA,CAAA,MAAA,CAAO,KAAK,IAAK,CAAA,SAAA,CAAU,IAAI,KAAO,EAAA,IAAA,EAAM,CAAC,CAAC,CAAA;AAElD,MAAI,IAAA,GAAA,CAAI,OAAO,OAAS,EAAA;AACtB,QAAA,GAAA,CAAI,MAAO,CAAA,IAAA,CAAK,GAAI,CAAA,KAAA,CAAM,OAAO,CAAA;AAAA;AAGnC,MAAI,IAAA,GAAA,CAAI,OAAO,aAAe,EAAA;AAC5B,QAAA,MAAM,KAAQ,GAAA,MAAM,gBAAiB,CAAA,GAAA,CAAI,aAAa,CAAA;AACtD,QAAA,GAAA,CAAI,MAAO,CAAA,IAAA;AAAA,UACT,CAAA;AAAA,EAAe,KAAA,CACZ,IAAI,CAAK,CAAA,KAAA;AACR,YAAA,MAAM,YAAe,GAAAC,aAAA,CAAS,GAAI,CAAA,aAAA,EAAe,CAAC,CAAA;AAClD,YAAI,IAAA,GAAA,CAAI,KAAO,EAAA,aAAA,KAAkB,eAAiB,EAAA;AAChD,cAAA,MAAM,OAAU,GAAAC,mBAAA,CAAG,YAAa,CAAA,CAAA,EAAG,OAAO,CAAA;AAC1C,cAAA,OAAO,MAAM,YAAY,CAAA;;AAAA,EAAA,EAAU,OAAO,CAAA,CAAA;AAAA;AAE5C,YAAA,OAAO,OAAO,YAAY,CAAA,CAAA;AAAA,WAC3B,CAAA,CACA,IAAK,CAAA,IAAI,CAAC,CAAA;AAAA,SACf;AAAA;AACF;AACF,GACD,CAAA;AACH;AAEA,eAAsB,iBAAiB,GAAgC,EAAA;AACrE,EAAM,MAAA,OAAA,GAAU,MAAMC,YAAA,CAAQ,GAAG,CAAA;AACjC,EAAM,MAAA,KAAA,GAAQ,MAAM,OAAQ,CAAA,GAAA;AAAA,IAC1B,OAAA,CAAQ,GAAI,CAAA,OAAM,MAAU,KAAA;AAC1B,MAAM,MAAA,GAAA,GAAMC,SAAK,CAAA,GAAA,EAAK,MAAM,CAAA;AAC5B,MAAQ,OAAA,CAAA,MAAMC,SAAK,CAAA,GAAG,CAAG,EAAA,WAAA,KAAgB,gBAAiB,CAAA,GAAG,CAAI,GAAA,CAAC,GAAG,CAAA;AAAA,KACtE;AAAA,GACH;AACA,EAAO,OAAA,KAAA,CAAM,MAAO,CAAA,CAAC,CAAG,EAAA,CAAA,KAAM,EAAE,MAAO,CAAA,CAAC,CAAG,EAAA,EAAE,CAAA;AAC/C;;;;;"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var pluginScaffolderNode = require('@backstage/plugin-scaffolder-node');
|
|
4
|
+
var z = require('zod');
|
|
5
|
+
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
6
|
+
var fs = require('fs/promises');
|
|
7
|
+
var path = require('path');
|
|
8
|
+
|
|
9
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
10
|
+
|
|
11
|
+
var z__default = /*#__PURE__*/_interopDefaultCompat(z);
|
|
12
|
+
var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
|
13
|
+
var path__default = /*#__PURE__*/_interopDefaultCompat(path);
|
|
14
|
+
|
|
15
|
+
const contentSchema = z__default.default.object({
|
|
16
|
+
name: z__default.default.string().describe("Name of the file or directory"),
|
|
17
|
+
path: z__default.default.string().describe("path to the file or directory relative to the workspace"),
|
|
18
|
+
fullPath: z__default.default.string().describe("full path to the file or directory")
|
|
19
|
+
});
|
|
20
|
+
const createFilesystemReadDirAction = () => {
|
|
21
|
+
return pluginScaffolderNode.createTemplateAction({
|
|
22
|
+
id: "fs:readdir",
|
|
23
|
+
description: "Reads files and directories from the workspace",
|
|
24
|
+
supportsDryRun: true,
|
|
25
|
+
schema: {
|
|
26
|
+
input: z__default.default.object({
|
|
27
|
+
paths: z__default.default.array(z__default.default.string().min(1)),
|
|
28
|
+
recursive: z__default.default.boolean().default(false)
|
|
29
|
+
}),
|
|
30
|
+
output: z__default.default.object({
|
|
31
|
+
files: z__default.default.array(contentSchema),
|
|
32
|
+
folders: z__default.default.array(contentSchema)
|
|
33
|
+
})
|
|
34
|
+
},
|
|
35
|
+
async handler(ctx) {
|
|
36
|
+
const files = [];
|
|
37
|
+
const folders = [];
|
|
38
|
+
for (const localPath of ctx.input.paths) {
|
|
39
|
+
const fullWorkspacePath = backendPluginApi.resolveSafeChildPath(
|
|
40
|
+
ctx.workspacePath,
|
|
41
|
+
localPath
|
|
42
|
+
);
|
|
43
|
+
const content = await fs__default.default.readdir(fullWorkspacePath, {
|
|
44
|
+
recursive: ctx.input.recursive,
|
|
45
|
+
withFileTypes: true
|
|
46
|
+
});
|
|
47
|
+
for (const dirent of content) {
|
|
48
|
+
const fullPath = path__default.default.join(dirent.parentPath, dirent.name);
|
|
49
|
+
const element = {
|
|
50
|
+
name: dirent.name,
|
|
51
|
+
path: path__default.default.relative(ctx.workspacePath, fullPath),
|
|
52
|
+
fullPath
|
|
53
|
+
};
|
|
54
|
+
if (dirent.isDirectory()) {
|
|
55
|
+
folders.push(element);
|
|
56
|
+
} else {
|
|
57
|
+
files.push(element);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
ctx.output("files", files);
|
|
62
|
+
ctx.output("folders", folders);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
exports.createFilesystemReadDirAction = createFilesystemReadDirAction;
|
|
68
|
+
//# sourceMappingURL=read.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read.cjs.js","sources":["../../../../../src/scaffolder/actions/builtin/filesystem/read.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { createTemplateAction } from '@backstage/plugin-scaffolder-node';\nimport z from 'zod';\nimport { resolveSafeChildPath } from '@backstage/backend-plugin-api';\nimport fs from 'fs/promises';\nimport path from 'path';\n\nconst contentSchema = z.object({\n name: z.string().describe('Name of the file or directory'),\n path: z\n .string()\n .describe('path to the file or directory relative to the workspace'),\n fullPath: z.string().describe('full path to the file or directory'),\n});\ntype Content = z.infer<typeof contentSchema>;\n\n/**\n * Creates new action that enables reading directories in the workspace.\n * @public\n */\nexport const createFilesystemReadDirAction = () => {\n return createTemplateAction({\n id: 'fs:readdir',\n description: 'Reads files and directories from the workspace',\n supportsDryRun: true,\n schema: {\n input: z.object({\n paths: z.array(z.string().min(1)),\n recursive: z.boolean().default(false),\n }),\n output: z.object({\n files: z.array(contentSchema),\n folders: z.array(contentSchema),\n }),\n },\n async handler(ctx) {\n const files: Content[] = [];\n const folders: Content[] = [];\n\n for (const localPath of ctx.input.paths) {\n const fullWorkspacePath = resolveSafeChildPath(\n ctx.workspacePath,\n localPath,\n );\n const content = await fs.readdir(fullWorkspacePath, {\n recursive: ctx.input.recursive,\n withFileTypes: true,\n });\n for (const dirent of content) {\n const fullPath = path.join(dirent.parentPath, dirent.name);\n const element = {\n name: dirent.name,\n path: path.relative(ctx.workspacePath, fullPath),\n fullPath,\n };\n if (dirent.isDirectory()) {\n folders.push(element);\n } else {\n files.push(element);\n }\n }\n }\n\n ctx.output('files', files);\n ctx.output('folders', folders);\n },\n });\n};\n"],"names":["z","createTemplateAction","resolveSafeChildPath","fs","path"],"mappings":";;;;;;;;;;;;;;AAqBA,MAAM,aAAA,GAAgBA,mBAAE,MAAO,CAAA;AAAA,EAC7B,IAAM,EAAAA,kBAAA,CAAE,MAAO,EAAA,CAAE,SAAS,+BAA+B,CAAA;AAAA,EACzD,IAAM,EAAAA,kBAAA,CACH,MAAO,EAAA,CACP,SAAS,yDAAyD,CAAA;AAAA,EACrE,QAAU,EAAAA,kBAAA,CAAE,MAAO,EAAA,CAAE,SAAS,oCAAoC;AACpE,CAAC,CAAA;AAOM,MAAM,gCAAgC,MAAM;AACjD,EAAA,OAAOC,yCAAqB,CAAA;AAAA,IAC1B,EAAI,EAAA,YAAA;AAAA,IACJ,WAAa,EAAA,gDAAA;AAAA,IACb,cAAgB,EAAA,IAAA;AAAA,IAChB,MAAQ,EAAA;AAAA,MACN,KAAA,EAAOD,mBAAE,MAAO,CAAA;AAAA,QACd,KAAA,EAAOA,mBAAE,KAAM,CAAAA,kBAAA,CAAE,QAAS,CAAA,GAAA,CAAI,CAAC,CAAC,CAAA;AAAA,QAChC,SAAW,EAAAA,kBAAA,CAAE,OAAQ,EAAA,CAAE,QAAQ,KAAK;AAAA,OACrC,CAAA;AAAA,MACD,MAAA,EAAQA,mBAAE,MAAO,CAAA;AAAA,QACf,KAAA,EAAOA,kBAAE,CAAA,KAAA,CAAM,aAAa,CAAA;AAAA,QAC5B,OAAA,EAASA,kBAAE,CAAA,KAAA,CAAM,aAAa;AAAA,OAC/B;AAAA,KACH;AAAA,IACA,MAAM,QAAQ,GAAK,EAAA;AACjB,MAAA,MAAM,QAAmB,EAAC;AAC1B,MAAA,MAAM,UAAqB,EAAC;AAE5B,MAAW,KAAA,MAAA,SAAA,IAAa,GAAI,CAAA,KAAA,CAAM,KAAO,EAAA;AACvC,QAAA,MAAM,iBAAoB,GAAAE,qCAAA;AAAA,UACxB,GAAI,CAAA,aAAA;AAAA,UACJ;AAAA,SACF;AACA,QAAA,MAAM,OAAU,GAAA,MAAMC,mBAAG,CAAA,OAAA,CAAQ,iBAAmB,EAAA;AAAA,UAClD,SAAA,EAAW,IAAI,KAAM,CAAA,SAAA;AAAA,UACrB,aAAe,EAAA;AAAA,SAChB,CAAA;AACD,QAAA,KAAA,MAAW,UAAU,OAAS,EAAA;AAC5B,UAAA,MAAM,WAAWC,qBAAK,CAAA,IAAA,CAAK,MAAO,CAAA,UAAA,EAAY,OAAO,IAAI,CAAA;AACzD,UAAA,MAAM,OAAU,GAAA;AAAA,YACd,MAAM,MAAO,CAAA,IAAA;AAAA,YACb,IAAM,EAAAA,qBAAA,CAAK,QAAS,CAAA,GAAA,CAAI,eAAe,QAAQ,CAAA;AAAA,YAC/C;AAAA,WACF;AACA,UAAI,IAAA,MAAA,CAAO,aAAe,EAAA;AACxB,YAAA,OAAA,CAAQ,KAAK,OAAO,CAAA;AAAA,WACf,MAAA;AACL,YAAA,KAAA,CAAM,KAAK,OAAO,CAAA;AAAA;AACpB;AACF;AAGF,MAAI,GAAA,CAAA,MAAA,CAAO,SAAS,KAAK,CAAA;AACzB,MAAI,GAAA,CAAA,MAAA,CAAO,WAAW,OAAO,CAAA;AAAA;AAC/B,GACD,CAAA;AACH;;;;"}
|
|
@@ -26,6 +26,7 @@ require('../actions/builtin/fetch/template.examples.cjs.js');
|
|
|
26
26
|
require('../actions/builtin/fetch/templateFile.examples.cjs.js');
|
|
27
27
|
require('../actions/builtin/filesystem/delete.examples.cjs.js');
|
|
28
28
|
require('../actions/builtin/filesystem/rename.examples.cjs.js');
|
|
29
|
+
require('../actions/builtin/filesystem/read.cjs.js');
|
|
29
30
|
require('@backstage/plugin-scaffolder-backend-module-github');
|
|
30
31
|
require('@backstage/plugin-scaffolder-backend-module-azure');
|
|
31
32
|
require('@backstage/plugin-scaffolder-backend-module-bitbucket');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DecoratedActionsRegistry.cjs.js","sources":["../../../src/scaffolder/dryrun/DecoratedActionsRegistry.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 { TemplateAction } from '@backstage/plugin-scaffolder-node';\nimport { TemplateActionRegistry } from '../actions';\n\n/** @internal */\nexport class DecoratedActionsRegistry extends TemplateActionRegistry {\n constructor(\n private readonly innerRegistry: TemplateActionRegistry,\n extraActions: Array<TemplateAction>,\n ) {\n super();\n for (const action of extraActions) {\n this.register(action);\n }\n }\n\n get(actionId: string): TemplateAction {\n try {\n return super.get(actionId);\n } catch {\n return this.innerRegistry.get(actionId);\n }\n }\n}\n"],"names":["TemplateActionRegistry"],"mappings":"
|
|
1
|
+
{"version":3,"file":"DecoratedActionsRegistry.cjs.js","sources":["../../../src/scaffolder/dryrun/DecoratedActionsRegistry.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 { TemplateAction } from '@backstage/plugin-scaffolder-node';\nimport { TemplateActionRegistry } from '../actions';\n\n/** @internal */\nexport class DecoratedActionsRegistry extends TemplateActionRegistry {\n constructor(\n private readonly innerRegistry: TemplateActionRegistry,\n extraActions: Array<TemplateAction>,\n ) {\n super();\n for (const action of extraActions) {\n this.register(action);\n }\n }\n\n get(actionId: string): TemplateAction {\n try {\n return super.get(actionId);\n } catch {\n return this.innerRegistry.get(actionId);\n }\n }\n}\n"],"names":["TemplateActionRegistry"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoBO,MAAM,iCAAiCA,6CAAuB,CAAA;AAAA,EACnE,WAAA,CACmB,eACjB,YACA,EAAA;AACA,IAAM,KAAA,EAAA;AAHW,IAAA,IAAA,CAAA,aAAA,GAAA,aAAA;AAIjB,IAAA,KAAA,MAAW,UAAU,YAAc,EAAA;AACjC,MAAA,IAAA,CAAK,SAAS,MAAM,CAAA;AAAA;AACtB;AACF,EAEA,IAAI,QAAkC,EAAA;AACpC,IAAI,IAAA;AACF,MAAO,OAAA,KAAA,CAAM,IAAI,QAAQ,CAAA;AAAA,KACnB,CAAA,MAAA;AACN,MAAO,OAAA,IAAA,CAAK,aAAc,CAAA,GAAA,CAAI,QAAQ,CAAA;AAAA;AACxC;AAEJ;;;;"}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var uuid = require('uuid');
|
|
4
3
|
var url = require('url');
|
|
5
4
|
var pluginScaffolderNode = require('@backstage/plugin-scaffolder-node');
|
|
5
|
+
var path = require('path');
|
|
6
6
|
var NunjucksWorkflowRunner = require('../tasks/NunjucksWorkflowRunner.cjs.js');
|
|
7
7
|
var DecoratedActionsRegistry = require('./DecoratedActionsRegistry.cjs.js');
|
|
8
8
|
var fs = require('fs-extra');
|
|
9
|
-
var
|
|
9
|
+
var uuid = require('uuid');
|
|
10
10
|
|
|
11
11
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
12
12
|
|
|
13
|
+
var path__default = /*#__PURE__*/_interopDefaultCompat(path);
|
|
13
14
|
var fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
|
14
15
|
|
|
15
16
|
function createDryRunner(options) {
|
|
@@ -29,12 +30,14 @@ function createDryRunner(options) {
|
|
|
29
30
|
})
|
|
30
31
|
])
|
|
31
32
|
});
|
|
33
|
+
const baseUrl = input.templateInfo.baseUrl;
|
|
34
|
+
if (!baseUrl) {
|
|
35
|
+
throw new Error("baseUrl is required");
|
|
36
|
+
}
|
|
37
|
+
const basePath = url.fileURLToPath(new URL(baseUrl));
|
|
38
|
+
const contentsPath = path__default.default.dirname(basePath);
|
|
32
39
|
const dryRunId = uuid.v4();
|
|
33
40
|
const log = new Array();
|
|
34
|
-
const contentsPath = backendPluginApi.resolveSafeChildPath(
|
|
35
|
-
options.workingDirectory,
|
|
36
|
-
`dry-run-content-${dryRunId}`
|
|
37
|
-
);
|
|
38
41
|
try {
|
|
39
42
|
await pluginScaffolderNode.deserializeDirectoryContents(contentsPath, input.directoryContents);
|
|
40
43
|
const abortSignal = new AbortController().signal;
|
|
@@ -49,12 +52,7 @@ function createDryRunner(options) {
|
|
|
49
52
|
action: "dry-run:extract"
|
|
50
53
|
}
|
|
51
54
|
],
|
|
52
|
-
templateInfo:
|
|
53
|
-
entityRef: "template:default/dry-run",
|
|
54
|
-
baseUrl: url.pathToFileURL(
|
|
55
|
-
backendPluginApi.resolveSafeChildPath(contentsPath, "template.yaml")
|
|
56
|
-
).toString()
|
|
57
|
-
}
|
|
55
|
+
templateInfo: input.templateInfo
|
|
58
56
|
},
|
|
59
57
|
secrets: input.secrets,
|
|
60
58
|
getInitiatorCredentials: () => Promise.resolve(input.credentials),
|
|
@@ -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 { ScmIntegrations } from '@backstage/integration';\nimport { TaskSpec } from '@backstage/plugin-scaffolder-common';\nimport { JsonObject } from '@backstage/types';\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 { ScmIntegrations } from '@backstage/integration';\nimport { TaskSpec, TemplateInfo } from '@backstage/plugin-scaffolder-common';\nimport { JsonObject } from '@backstage/types';\nimport { fileURLToPath } from 'url';\nimport { Logger } from 'winston';\nimport {\n createTemplateAction,\n TaskSecrets,\n TemplateFilter,\n TemplateGlobal,\n deserializeDirectoryContents,\n SerializedFile,\n serializeDirectoryContents,\n} from '@backstage/plugin-scaffolder-node';\nimport path from 'path';\nimport { TemplateActionRegistry } from '../actions';\nimport { NunjucksWorkflowRunner } from '../tasks/NunjucksWorkflowRunner';\nimport { DecoratedActionsRegistry } from './DecoratedActionsRegistry';\nimport fs from 'fs-extra';\nimport { PermissionEvaluator } from '@backstage/plugin-permission-common';\nimport { BackstageCredentials } from '@backstage/backend-plugin-api';\nimport type { UserEntity } from '@backstage/catalog-model';\nimport { v4 as uuid } from 'uuid';\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<{ body: JsonObject }>;\n directoryContents: SerializedFile[];\n output: JsonObject;\n}\n\n/** @internal */\nexport type TemplateTesterCreateOptions = {\n logger: Logger;\n integrations: ScmIntegrations;\n actionRegistry: TemplateActionRegistry;\n workingDirectory: string;\n additionalTemplateFilters?: Record<string, TemplateFilter>;\n additionalTemplateGlobals?: Record<string, TemplateGlobal>;\n permissions?: PermissionEvaluator;\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 });\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<{ body: JsonObject }>();\n\n try {\n await deserializeDirectoryContents(contentsPath, input.directoryContents);\n\n const abortSignal = new AbortController().signal;\n const result = await workflowRunner.execute({\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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"}
|
|
@@ -10,12 +10,12 @@ var alpha = require('@backstage/plugin-scaffolder-common/alpha');
|
|
|
10
10
|
var express = require('express');
|
|
11
11
|
var Router = require('express-promise-router');
|
|
12
12
|
var jsonschema = require('jsonschema');
|
|
13
|
-
var
|
|
13
|
+
var z = require('zod');
|
|
14
14
|
require('@backstage/plugin-scaffolder-node');
|
|
15
15
|
require('../scaffolder/actions/builtin/catalog/register.examples.cjs.js');
|
|
16
16
|
require('fs-extra');
|
|
17
17
|
require('yaml');
|
|
18
|
-
require('@backstage/backend-plugin-api');
|
|
18
|
+
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
19
19
|
require('../scaffolder/actions/builtin/catalog/write.examples.cjs.js');
|
|
20
20
|
require('../scaffolder/actions/builtin/catalog/fetch.examples.cjs.js');
|
|
21
21
|
var createBuiltinActions = require('../scaffolder/actions/builtin/createBuiltinActions.cjs.js');
|
|
@@ -34,6 +34,7 @@ require('../scaffolder/actions/builtin/fetch/template.examples.cjs.js');
|
|
|
34
34
|
require('../scaffolder/actions/builtin/fetch/templateFile.examples.cjs.js');
|
|
35
35
|
require('../scaffolder/actions/builtin/filesystem/delete.examples.cjs.js');
|
|
36
36
|
require('../scaffolder/actions/builtin/filesystem/rename.examples.cjs.js');
|
|
37
|
+
require('../scaffolder/actions/builtin/filesystem/read.cjs.js');
|
|
37
38
|
require('@backstage/plugin-scaffolder-backend-module-github');
|
|
38
39
|
require('@backstage/plugin-scaffolder-backend-module-gitlab');
|
|
39
40
|
require('@backstage/plugin-scaffolder-backend-module-azure');
|
|
@@ -50,6 +51,8 @@ var helpers = require('./helpers.cjs.js');
|
|
|
50
51
|
var pluginPermissionNode = require('@backstage/plugin-permission-node');
|
|
51
52
|
var rules = require('./rules.cjs.js');
|
|
52
53
|
var checkPermissions = require('../util/checkPermissions.cjs.js');
|
|
54
|
+
var url = require('url');
|
|
55
|
+
var uuid = require('uuid');
|
|
53
56
|
|
|
54
57
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
|
|
55
58
|
|
|
@@ -524,12 +527,12 @@ data: ${JSON.stringify(event)}
|
|
|
524
527
|
permissions: [alpha.taskCreatePermission],
|
|
525
528
|
permissionService: permissions
|
|
526
529
|
});
|
|
527
|
-
const bodySchema =
|
|
528
|
-
template:
|
|
529
|
-
values:
|
|
530
|
-
secrets:
|
|
531
|
-
directoryContents:
|
|
532
|
-
|
|
530
|
+
const bodySchema = z.z.object({
|
|
531
|
+
template: z.z.unknown(),
|
|
532
|
+
values: z.z.record(z.z.unknown()),
|
|
533
|
+
secrets: z.z.record(z.z.string()).optional(),
|
|
534
|
+
directoryContents: z.z.array(
|
|
535
|
+
z.z.object({ path: z.z.string(), base64Content: z.z.string() })
|
|
533
536
|
)
|
|
534
537
|
});
|
|
535
538
|
const body = await bodySchema.parseAsync(req.body).catch((e) => {
|
|
@@ -557,6 +560,20 @@ data: ${JSON.stringify(event)}
|
|
|
557
560
|
id: step.id ?? `step-${index + 1}`,
|
|
558
561
|
name: step.name ?? step.action
|
|
559
562
|
}));
|
|
563
|
+
const dryRunId = uuid.v4();
|
|
564
|
+
const contentsPath = backendPluginApi.resolveSafeChildPath(
|
|
565
|
+
workingDirectory,
|
|
566
|
+
`dry-run-content-${dryRunId}`
|
|
567
|
+
);
|
|
568
|
+
const templateInfo = {
|
|
569
|
+
entityRef: catalogModel.stringifyEntityRef(template),
|
|
570
|
+
entity: {
|
|
571
|
+
metadata: template.metadata
|
|
572
|
+
},
|
|
573
|
+
baseUrl: url.pathToFileURL(
|
|
574
|
+
backendPluginApi.resolveSafeChildPath(contentsPath, "template.yaml")
|
|
575
|
+
).toString()
|
|
576
|
+
};
|
|
560
577
|
const result = await dryRunner({
|
|
561
578
|
spec: {
|
|
562
579
|
apiVersion: template.apiVersion,
|
|
@@ -568,6 +585,7 @@ data: ${JSON.stringify(event)}
|
|
|
568
585
|
ref: userEntityRef
|
|
569
586
|
}
|
|
570
587
|
},
|
|
588
|
+
templateInfo,
|
|
571
589
|
directoryContents: (body.directoryContents ?? []).map((file) => ({
|
|
572
590
|
path: file.path,
|
|
573
591
|
content: Buffer.from(file.base64Content, "base64")
|
|
@@ -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 createLegacyAuthAdapters,\n HostDiscovery,\n} from '@backstage/backend-common';\nimport { CatalogApi } from '@backstage/catalog-client';\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, stringifyError } from '@backstage/errors';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { HumanDuration, JsonObject, JsonValue } from '@backstage/types';\nimport {\n TaskSpec,\n TemplateEntityStepV1beta3,\n TemplateEntityV1beta3,\n templateEntityV1beta3Validator,\n TemplateParametersV1beta3,\n} from '@backstage/plugin-scaffolder-common';\nimport {\n RESOURCE_TYPE_SCAFFOLDER_ACTION,\n RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,\n scaffolderActionPermissions,\n scaffolderTaskPermissions,\n scaffolderTemplatePermissions,\n taskCancelPermission,\n taskCreatePermission,\n taskReadPermission,\n templateParameterReadPermission,\n templateStepReadPermission,\n} from '@backstage/plugin-scaffolder-common/alpha';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport { validate } from 'jsonschema';\nimport { Logger } from 'winston';\nimport { z } from 'zod';\nimport {\n TaskBroker,\n TaskStatus,\n TemplateAction,\n TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport {\n createBuiltinActions,\n DatabaseTaskStore,\n TaskWorker,\n TemplateActionRegistry,\n} from '../scaffolder';\nimport { createDryRunner } from '../scaffolder/dryrun';\nimport { StorageTaskBroker } from '../scaffolder/tasks/StorageTaskBroker';\nimport {\n findTemplate,\n getEntityBaseUrl,\n getWorkingDirectory,\n parseNumberParam,\n parseStringsParam,\n} from './helpers';\nimport { PermissionRuleParams } from '@backstage/plugin-permission-common';\nimport {\n createConditionAuthorizer,\n createPermissionIntegrationRouter,\n PermissionRule,\n} from '@backstage/plugin-permission-node';\nimport { scaffolderActionRules, scaffolderTemplateRules } from './rules';\nimport { Duration } from 'luxon';\nimport {\n AuthService,\n BackstageCredentials,\n DatabaseService,\n DiscoveryService,\n HttpAuthService,\n LifecycleService,\n PermissionsService,\n SchedulerService,\n UrlReaderService,\n} from '@backstage/backend-plugin-api';\nimport {\n IdentityApi,\n IdentityApiGetIdentityRequest,\n} from '@backstage/plugin-auth-node';\nimport { InternalTaskSecrets } from '../scaffolder/tasks/types';\nimport { checkPermission } from '../util/checkPermissions';\nimport {\n AutocompleteHandler,\n WorkspaceProvider,\n} from '@backstage/plugin-scaffolder-node/alpha';\n\n/**\n *\n * @public\n */\nexport type TemplatePermissionRuleInput<\n TParams extends PermissionRuleParams = PermissionRuleParams,\n> = PermissionRule<\n TemplateEntityStepV1beta3 | TemplateParametersV1beta3,\n {},\n typeof RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,\n TParams\n>;\nfunction isTemplatePermissionRuleInput(\n permissionRule: TemplatePermissionRuleInput | ActionPermissionRuleInput,\n): permissionRule is TemplatePermissionRuleInput {\n return permissionRule.resourceType === RESOURCE_TYPE_SCAFFOLDER_TEMPLATE;\n}\n\n/**\n *\n * @public\n */\nexport type ActionPermissionRuleInput<\n TParams extends PermissionRuleParams = PermissionRuleParams,\n> = PermissionRule<\n TemplateEntityStepV1beta3 | TemplateParametersV1beta3,\n {},\n typeof RESOURCE_TYPE_SCAFFOLDER_ACTION,\n TParams\n>;\nfunction isActionPermissionRuleInput(\n permissionRule: TemplatePermissionRuleInput | ActionPermissionRuleInput,\n): permissionRule is ActionPermissionRuleInput {\n return permissionRule.resourceType === RESOURCE_TYPE_SCAFFOLDER_ACTION;\n}\n\n/**\n * RouterOptions\n *\n * @public\n * @deprecated Please migrate to the new backend system as this will be removed in the future.\n */\nexport interface RouterOptions {\n logger: Logger;\n config: Config;\n reader: UrlReaderService;\n lifecycle?: LifecycleService;\n database: DatabaseService;\n catalogClient: CatalogApi;\n scheduler?: SchedulerService;\n actions?: TemplateAction<any, any>[];\n /**\n * @deprecated taskWorkers is deprecated in favor of concurrentTasksLimit option with a single TaskWorker\n * @defaultValue 1\n */\n taskWorkers?: number;\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?: Record<string, TemplateFilter>;\n additionalTemplateGlobals?: Record<string, TemplateGlobal>;\n additionalWorkspaceProviders?: Record<string, WorkspaceProvider>;\n permissions?: PermissionsService;\n permissionRules?: Array<\n TemplatePermissionRuleInput | ActionPermissionRuleInput\n >;\n auth?: AuthService;\n httpAuth?: HttpAuthService;\n identity?: IdentityApi;\n discovery?: DiscoveryService;\n\n autocompleteHandlers?: Record<string, AutocompleteHandler>;\n}\n\nfunction isSupportedTemplate(entity: TemplateEntityV1beta3) {\n return entity.apiVersion === 'scaffolder.backstage.io/v1beta3';\n}\n\n/*\n * @deprecated This function remains as the DefaultIdentityClient behaves slightly differently to the pre-existing\n * scaffolder behaviour. Specifically if the token fails to parse, the DefaultIdentityClient will raise an error.\n * The scaffolder did not raise an error in this case. As such we chose to allow it to behave as it did previously\n * until someone explicitly passes an IdentityApi. When we have reasonable confidence that most backstage deployments\n * are using the IdentityApi, we can remove this function.\n */\nfunction buildDefaultIdentityClient(options: RouterOptions): IdentityApi {\n return {\n getIdentity: async ({ request }: IdentityApiGetIdentityRequest) => {\n const header = request.headers.authorization;\n const { logger } = options;\n\n if (!header) {\n return undefined;\n }\n\n try {\n const token = header.match(/^Bearer\\s(\\S+\\.\\S+\\.\\S+)$/i)?.[1];\n if (!token) {\n throw new TypeError('Expected Bearer with JWT');\n }\n\n const [_header, rawPayload, _signature] = token.split('.');\n const payload: JsonValue = JSON.parse(\n Buffer.from(rawPayload, 'base64').toString(),\n );\n\n if (\n typeof payload !== 'object' ||\n payload === null ||\n Array.isArray(payload)\n ) {\n throw new TypeError('Malformed JWT payload');\n }\n\n const sub = payload.sub;\n if (typeof sub !== 'string') {\n throw new TypeError('Expected string sub claim');\n }\n\n if (sub === 'backstage-server') {\n return undefined;\n }\n\n // Check that it's a valid ref, otherwise this will throw.\n parseEntityRef(sub);\n\n return {\n identity: {\n userEntityRef: sub,\n ownershipEntityRefs: [],\n type: 'user',\n },\n token,\n };\n } catch (e) {\n logger.error(`Invalid authorization header: ${stringifyError(e)}`);\n return undefined;\n }\n },\n };\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\n/**\n * A method to create a router for the scaffolder backend plugin.\n * @public\n * @deprecated Please migrate to the new backend system as this will be removed in the future.\n */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const router = Router();\n // Be generous in upload size to support a wide range of templates in dry-run mode.\n router.use(express.json({ limit: '10MB' }));\n\n const {\n logger: parentLogger,\n config,\n reader,\n database,\n catalogClient,\n actions,\n taskWorkers,\n scheduler,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n additionalWorkspaceProviders,\n permissions,\n permissionRules,\n discovery = HostDiscovery.fromConfig(config),\n identity = buildDefaultIdentityClient(options),\n autocompleteHandlers = {},\n } = options;\n\n const { auth, httpAuth } = createLegacyAuthAdapters({\n ...options,\n identity,\n discovery,\n });\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({ database });\n taskBroker = new StorageTaskBroker(\n databaseTaskStore,\n logger,\n config,\n auth,\n additionalWorkspaceProviders,\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 TemplateActionRegistry();\n\n const workers: TaskWorker[] = [];\n if (concurrentTasksLimit !== 0) {\n for (let i = 0; i < (taskWorkers || 1); i++) {\n const worker = await TaskWorker.create({\n taskBroker,\n actionRegistry,\n integrations,\n logger,\n workingDirectory,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n concurrentTasksLimit,\n permissions,\n });\n workers.push(worker);\n }\n }\n\n const actionsToRegister = Array.isArray(actions)\n ? actions\n : createBuiltinActions({\n integrations,\n catalogClient,\n reader,\n config,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n auth,\n });\n\n actionsToRegister.forEach(action => actionRegistry.register(action));\n\n const launchWorkers = () => workers.forEach(worker => worker.start());\n\n const shutdownWorkers = () => {\n workers.forEach(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 workingDirectory,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n permissions,\n });\n\n const templateRules: TemplatePermissionRuleInput[] = Object.values(\n scaffolderTemplateRules,\n );\n const actionRules: ActionPermissionRuleInput[] = Object.values(\n scaffolderActionRules,\n );\n\n if (permissionRules) {\n templateRules.push(\n ...permissionRules.filter(isTemplatePermissionRuleInput),\n );\n actionRules.push(...permissionRules.filter(isActionPermissionRuleInput));\n }\n\n const isAuthorized = createConditionAuthorizer(Object.values(templateRules));\n\n const permissionIntegrationRouter = createPermissionIntegrationRouter({\n resources: [\n {\n resourceType: RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,\n permissions: scaffolderTemplatePermissions,\n rules: templateRules,\n },\n {\n resourceType: RESOURCE_TYPE_SCAFFOLDER_ACTION,\n permissions: scaffolderActionPermissions,\n rules: actionRules,\n },\n ],\n permissions: scaffolderTaskPermissions,\n });\n\n router.use(permissionIntegrationRouter);\n\n router\n .get(\n '/v2/templates/:namespace/:kind/:name/parameter-schema',\n async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: credentials,\n targetPluginId: 'catalog',\n });\n\n const template = await authorizeTemplate(\n req.params,\n token,\n credentials,\n );\n\n const parameters = [template.spec.parameters ?? []].flat();\n\n const presentation = template.spec.presentation;\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: schema.title ?? 'Please enter the following information',\n description: schema.description,\n schema,\n })),\n });\n },\n )\n .get('/v2/actions', async (_req, res) => {\n const actionsList = actionRegistry.list().map(action => {\n return {\n id: action.id,\n description: action.description,\n examples: action.examples,\n schema: action.schema,\n };\n });\n res.json(actionsList);\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 credentials = await httpAuth.credentials(req);\n\n await checkPermission({\n credentials,\n permissions: [taskCreatePermission],\n permissionService: permissions,\n });\n\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: credentials,\n targetPluginId: 'catalog',\n });\n\n const userEntityRef = auth.isPrincipal(credentials, 'user')\n ? credentials.principal.userEntityRef\n : undefined;\n\n const userEntity = userEntityRef\n ? await catalogClient.getEntityByRef(userEntityRef, { token })\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 token,\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 res.status(400).json({ errors: result.errors });\n return;\n }\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: 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 res.status(201).json({ id: result.taskId });\n })\n .get('/v2/tasks', async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n await checkPermission({\n credentials,\n permissions: [taskReadPermission],\n permissionService: permissions,\n });\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 = parseNumberParam(req.query.limit, 'limit');\n const offset = parseNumberParam(req.query.offset, 'offset');\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: limit ? limit[0] : undefined,\n offset: offset ? offset[0] : undefined,\n },\n });\n\n res.status(200).json(tasks);\n })\n .get('/v2/tasks/:taskId', async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n await checkPermission({\n credentials,\n permissions: [taskReadPermission],\n permissionService: permissions,\n });\n\n const { taskId } = req.params;\n const task = await taskBroker.get(taskId);\n if (!task) {\n throw new NotFoundError(`Task with id ${taskId} does not exist`);\n }\n // Do not disclose secrets\n delete task.secrets;\n res.status(200).json(task);\n })\n .post('/v2/tasks/:taskId/cancel', async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n // Requires both read and cancel permissions\n await checkPermission({\n credentials,\n permissions: [taskCancelPermission, taskReadPermission],\n permissionService: permissions,\n });\n\n const { taskId } = req.params;\n await taskBroker.cancel?.(taskId);\n res.status(200).json({ status: 'cancelled' });\n })\n .post('/v2/tasks/:taskId/retry', async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n // Requires both read and cancel permissions\n await checkPermission({\n credentials,\n permissions: [taskCreatePermission, taskReadPermission],\n permissionService: permissions,\n });\n\n const { taskId } = req.params;\n await taskBroker.retry?.(taskId);\n res.status(201).json({ id: taskId });\n })\n .get('/v2/tasks/:taskId/eventstream', async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n await checkPermission({\n credentials,\n permissions: [taskReadPermission],\n permissionService: permissions,\n });\n\n const { taskId } = req.params;\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: error => {\n logger.error(\n `Received error from event stream when observing taskId '${taskId}', ${error}`,\n );\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', () => {\n subscription.unsubscribe();\n logger.debug(`Event stream observing taskId '${taskId}' closed`);\n });\n })\n .get('/v2/tasks/:taskId/events', async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n await checkPermission({\n credentials,\n permissions: [taskReadPermission],\n permissionService: permissions,\n });\n\n const { taskId } = req.params;\n const after = 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: error => {\n logger.error(\n `Received error from event stream when observing taskId '${taskId}', ${error}`,\n );\n },\n next: ({ events }) => {\n clearTimeout(timeout);\n subscription.unsubscribe();\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 })\n .post('/v2/dry-run', async (req, res) => {\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 { token } = await auth.getPluginRequestToken({\n onBehalfOf: credentials,\n targetPluginId: 'catalog',\n });\n\n const userEntityRef = auth.isPrincipal(credentials, 'user')\n ? credentials.principal.userEntityRef\n : undefined;\n\n const userEntity = userEntityRef\n ? await catalogClient.getEntityByRef(userEntityRef, { token })\n : undefined;\n\n for (const parameters of [template.spec.parameters ?? []].flat()) {\n const result = validate(body.values, parameters);\n if (!result.valid) {\n res.status(400).json({ errors: result.errors });\n return;\n }\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 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 directoryContents: (body.directoryContents ?? []).map(file => ({\n path: file.path,\n content: Buffer.from(file.base64Content, 'base64'),\n })),\n secrets: {\n ...body.secrets,\n ...(token && { backstageToken: token }),\n },\n credentials,\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 })\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\n const app = express();\n app.set('logger', logger);\n app.use('/', router);\n\n async function authorizeTemplate(\n entityRef: CompoundEntityRef,\n token: string | undefined,\n credentials: BackstageCredentials,\n ) {\n const template = await findTemplate({\n catalogApi: catalogClient,\n entityRef,\n token,\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 isAuthorized(parameterDecision, step),\n );\n } else if (\n template.spec.parameters &&\n !isAuthorized(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 isAuthorized(stepDecision, step),\n );\n\n return template;\n }\n\n return app;\n}\n"],"names":["RESOURCE_TYPE_SCAFFOLDER_TEMPLATE","RESOURCE_TYPE_SCAFFOLDER_ACTION","parseEntityRef","stringifyError","config","readDurationFromConfig","Router","express","HostDiscovery","createLegacyAuthAdapters","getWorkingDirectory","ScmIntegrations","DatabaseTaskStore","StorageTaskBroker","Duration","TemplateActionRegistry","TaskWorker","createBuiltinActions","createDryRunner","scaffolderTemplateRules","scaffolderActionRules","createConditionAuthorizer","createPermissionIntegrationRouter","scaffolderTemplatePermissions","scaffolderActionPermissions","scaffolderTaskPermissions","checkPermission","taskCreatePermission","result","validate","getEntityBaseUrl","stringifyEntityRef","taskReadPermission","parseStringsParam","InputError","parseNumberParam","NotFoundError","taskCancelPermission","z","templateEntityV1beta3Validator","findTemplate","templateParameterReadPermission","templateStepReadPermission"],"mappings":"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"}
|
|
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 createLegacyAuthAdapters,\n HostDiscovery,\n} from '@backstage/backend-common';\nimport { CatalogApi } from '@backstage/catalog-client';\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, stringifyError } from '@backstage/errors';\nimport { ScmIntegrations } from '@backstage/integration';\nimport { HumanDuration, JsonObject, JsonValue } from '@backstage/types';\nimport {\n TaskSpec,\n TemplateEntityStepV1beta3,\n TemplateEntityV1beta3,\n templateEntityV1beta3Validator,\n TemplateParametersV1beta3,\n} from '@backstage/plugin-scaffolder-common';\nimport {\n RESOURCE_TYPE_SCAFFOLDER_ACTION,\n RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,\n scaffolderActionPermissions,\n scaffolderTaskPermissions,\n scaffolderTemplatePermissions,\n taskCancelPermission,\n taskCreatePermission,\n taskReadPermission,\n templateParameterReadPermission,\n templateStepReadPermission,\n} from '@backstage/plugin-scaffolder-common/alpha';\nimport express from 'express';\nimport Router from 'express-promise-router';\nimport { validate } from 'jsonschema';\nimport { Logger } from 'winston';\nimport { z } from 'zod';\nimport {\n TaskBroker,\n TaskStatus,\n TemplateAction,\n TemplateFilter,\n TemplateGlobal,\n} from '@backstage/plugin-scaffolder-node';\nimport {\n createBuiltinActions,\n DatabaseTaskStore,\n TaskWorker,\n TemplateActionRegistry,\n} from '../scaffolder';\nimport { createDryRunner } from '../scaffolder/dryrun';\nimport { StorageTaskBroker } from '../scaffolder/tasks/StorageTaskBroker';\nimport {\n findTemplate,\n getEntityBaseUrl,\n getWorkingDirectory,\n parseNumberParam,\n parseStringsParam,\n} from './helpers';\nimport { PermissionRuleParams } from '@backstage/plugin-permission-common';\nimport {\n createConditionAuthorizer,\n createPermissionIntegrationRouter,\n PermissionRule,\n} from '@backstage/plugin-permission-node';\nimport { scaffolderActionRules, scaffolderTemplateRules } from './rules';\nimport { Duration } from 'luxon';\nimport {\n AuthService,\n BackstageCredentials,\n DatabaseService,\n DiscoveryService,\n HttpAuthService,\n LifecycleService,\n PermissionsService,\n SchedulerService,\n UrlReaderService,\n resolveSafeChildPath,\n} from '@backstage/backend-plugin-api';\nimport {\n IdentityApi,\n IdentityApiGetIdentityRequest,\n} from '@backstage/plugin-auth-node';\nimport { InternalTaskSecrets } from '../scaffolder/tasks/types';\nimport { checkPermission } from '../util/checkPermissions';\nimport {\n AutocompleteHandler,\n WorkspaceProvider,\n} from '@backstage/plugin-scaffolder-node/alpha';\nimport { pathToFileURL } from 'url';\nimport { v4 as uuid } from 'uuid';\n\n/**\n *\n * @public\n */\nexport type TemplatePermissionRuleInput<\n TParams extends PermissionRuleParams = PermissionRuleParams,\n> = PermissionRule<\n TemplateEntityStepV1beta3 | TemplateParametersV1beta3,\n {},\n typeof RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,\n TParams\n>;\nfunction isTemplatePermissionRuleInput(\n permissionRule: TemplatePermissionRuleInput | ActionPermissionRuleInput,\n): permissionRule is TemplatePermissionRuleInput {\n return permissionRule.resourceType === RESOURCE_TYPE_SCAFFOLDER_TEMPLATE;\n}\n\n/**\n *\n * @public\n */\nexport type ActionPermissionRuleInput<\n TParams extends PermissionRuleParams = PermissionRuleParams,\n> = PermissionRule<\n TemplateEntityStepV1beta3 | TemplateParametersV1beta3,\n {},\n typeof RESOURCE_TYPE_SCAFFOLDER_ACTION,\n TParams\n>;\nfunction isActionPermissionRuleInput(\n permissionRule: TemplatePermissionRuleInput | ActionPermissionRuleInput,\n): permissionRule is ActionPermissionRuleInput {\n return permissionRule.resourceType === RESOURCE_TYPE_SCAFFOLDER_ACTION;\n}\n\n/**\n * RouterOptions\n *\n * @public\n * @deprecated Please migrate to the new backend system as this will be removed in the future.\n */\nexport interface RouterOptions {\n logger: Logger;\n config: Config;\n reader: UrlReaderService;\n lifecycle?: LifecycleService;\n database: DatabaseService;\n catalogClient: CatalogApi;\n scheduler?: SchedulerService;\n actions?: TemplateAction<any, any>[];\n /**\n * @deprecated taskWorkers is deprecated in favor of concurrentTasksLimit option with a single TaskWorker\n * @defaultValue 1\n */\n taskWorkers?: number;\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?: Record<string, TemplateFilter>;\n additionalTemplateGlobals?: Record<string, TemplateGlobal>;\n additionalWorkspaceProviders?: Record<string, WorkspaceProvider>;\n permissions?: PermissionsService;\n permissionRules?: Array<\n TemplatePermissionRuleInput | ActionPermissionRuleInput\n >;\n auth?: AuthService;\n httpAuth?: HttpAuthService;\n identity?: IdentityApi;\n discovery?: DiscoveryService;\n\n autocompleteHandlers?: Record<string, AutocompleteHandler>;\n}\n\nfunction isSupportedTemplate(entity: TemplateEntityV1beta3) {\n return entity.apiVersion === 'scaffolder.backstage.io/v1beta3';\n}\n\n/*\n * @deprecated This function remains as the DefaultIdentityClient behaves slightly differently to the pre-existing\n * scaffolder behaviour. Specifically if the token fails to parse, the DefaultIdentityClient will raise an error.\n * The scaffolder did not raise an error in this case. As such we chose to allow it to behave as it did previously\n * until someone explicitly passes an IdentityApi. When we have reasonable confidence that most backstage deployments\n * are using the IdentityApi, we can remove this function.\n */\nfunction buildDefaultIdentityClient(options: RouterOptions): IdentityApi {\n return {\n getIdentity: async ({ request }: IdentityApiGetIdentityRequest) => {\n const header = request.headers.authorization;\n const { logger } = options;\n\n if (!header) {\n return undefined;\n }\n\n try {\n const token = header.match(/^Bearer\\s(\\S+\\.\\S+\\.\\S+)$/i)?.[1];\n if (!token) {\n throw new TypeError('Expected Bearer with JWT');\n }\n\n const [_header, rawPayload, _signature] = token.split('.');\n const payload: JsonValue = JSON.parse(\n Buffer.from(rawPayload, 'base64').toString(),\n );\n\n if (\n typeof payload !== 'object' ||\n payload === null ||\n Array.isArray(payload)\n ) {\n throw new TypeError('Malformed JWT payload');\n }\n\n const sub = payload.sub;\n if (typeof sub !== 'string') {\n throw new TypeError('Expected string sub claim');\n }\n\n if (sub === 'backstage-server') {\n return undefined;\n }\n\n // Check that it's a valid ref, otherwise this will throw.\n parseEntityRef(sub);\n\n return {\n identity: {\n userEntityRef: sub,\n ownershipEntityRefs: [],\n type: 'user',\n },\n token,\n };\n } catch (e) {\n logger.error(`Invalid authorization header: ${stringifyError(e)}`);\n return undefined;\n }\n },\n };\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\n/**\n * A method to create a router for the scaffolder backend plugin.\n * @public\n * @deprecated Please migrate to the new backend system as this will be removed in the future.\n */\nexport async function createRouter(\n options: RouterOptions,\n): Promise<express.Router> {\n const router = Router();\n // Be generous in upload size to support a wide range of templates in dry-run mode.\n router.use(express.json({ limit: '10MB' }));\n\n const {\n logger: parentLogger,\n config,\n reader,\n database,\n catalogClient,\n actions,\n taskWorkers,\n scheduler,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n additionalWorkspaceProviders,\n permissions,\n permissionRules,\n discovery = HostDiscovery.fromConfig(config),\n identity = buildDefaultIdentityClient(options),\n autocompleteHandlers = {},\n } = options;\n\n const { auth, httpAuth } = createLegacyAuthAdapters({\n ...options,\n identity,\n discovery,\n });\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({ database });\n taskBroker = new StorageTaskBroker(\n databaseTaskStore,\n logger,\n config,\n auth,\n additionalWorkspaceProviders,\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 TemplateActionRegistry();\n\n const workers: TaskWorker[] = [];\n if (concurrentTasksLimit !== 0) {\n for (let i = 0; i < (taskWorkers || 1); i++) {\n const worker = await TaskWorker.create({\n taskBroker,\n actionRegistry,\n integrations,\n logger,\n workingDirectory,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n concurrentTasksLimit,\n permissions,\n });\n workers.push(worker);\n }\n }\n\n const actionsToRegister = Array.isArray(actions)\n ? actions\n : createBuiltinActions({\n integrations,\n catalogClient,\n reader,\n config,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n auth,\n });\n\n actionsToRegister.forEach(action => actionRegistry.register(action));\n\n const launchWorkers = () => workers.forEach(worker => worker.start());\n\n const shutdownWorkers = () => {\n workers.forEach(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 workingDirectory,\n additionalTemplateFilters,\n additionalTemplateGlobals,\n permissions,\n });\n\n const templateRules: TemplatePermissionRuleInput[] = Object.values(\n scaffolderTemplateRules,\n );\n const actionRules: ActionPermissionRuleInput[] = Object.values(\n scaffolderActionRules,\n );\n\n if (permissionRules) {\n templateRules.push(\n ...permissionRules.filter(isTemplatePermissionRuleInput),\n );\n actionRules.push(...permissionRules.filter(isActionPermissionRuleInput));\n }\n\n const isAuthorized = createConditionAuthorizer(Object.values(templateRules));\n\n const permissionIntegrationRouter = createPermissionIntegrationRouter({\n resources: [\n {\n resourceType: RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,\n permissions: scaffolderTemplatePermissions,\n rules: templateRules,\n },\n {\n resourceType: RESOURCE_TYPE_SCAFFOLDER_ACTION,\n permissions: scaffolderActionPermissions,\n rules: actionRules,\n },\n ],\n permissions: scaffolderTaskPermissions,\n });\n\n router.use(permissionIntegrationRouter);\n\n router\n .get(\n '/v2/templates/:namespace/:kind/:name/parameter-schema',\n async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: credentials,\n targetPluginId: 'catalog',\n });\n\n const template = await authorizeTemplate(\n req.params,\n token,\n credentials,\n );\n\n const parameters = [template.spec.parameters ?? []].flat();\n\n const presentation = template.spec.presentation;\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: schema.title ?? 'Please enter the following information',\n description: schema.description,\n schema,\n })),\n });\n },\n )\n .get('/v2/actions', async (_req, res) => {\n const actionsList = actionRegistry.list().map(action => {\n return {\n id: action.id,\n description: action.description,\n examples: action.examples,\n schema: action.schema,\n };\n });\n res.json(actionsList);\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 credentials = await httpAuth.credentials(req);\n\n await checkPermission({\n credentials,\n permissions: [taskCreatePermission],\n permissionService: permissions,\n });\n\n const { token } = await auth.getPluginRequestToken({\n onBehalfOf: credentials,\n targetPluginId: 'catalog',\n });\n\n const userEntityRef = auth.isPrincipal(credentials, 'user')\n ? credentials.principal.userEntityRef\n : undefined;\n\n const userEntity = userEntityRef\n ? await catalogClient.getEntityByRef(userEntityRef, { token })\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 token,\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 res.status(400).json({ errors: result.errors });\n return;\n }\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: 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 res.status(201).json({ id: result.taskId });\n })\n .get('/v2/tasks', async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n await checkPermission({\n credentials,\n permissions: [taskReadPermission],\n permissionService: permissions,\n });\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 = parseNumberParam(req.query.limit, 'limit');\n const offset = parseNumberParam(req.query.offset, 'offset');\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: limit ? limit[0] : undefined,\n offset: offset ? offset[0] : undefined,\n },\n });\n\n res.status(200).json(tasks);\n })\n .get('/v2/tasks/:taskId', async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n await checkPermission({\n credentials,\n permissions: [taskReadPermission],\n permissionService: permissions,\n });\n\n const { taskId } = req.params;\n const task = await taskBroker.get(taskId);\n if (!task) {\n throw new NotFoundError(`Task with id ${taskId} does not exist`);\n }\n // Do not disclose secrets\n delete task.secrets;\n res.status(200).json(task);\n })\n .post('/v2/tasks/:taskId/cancel', async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n // Requires both read and cancel permissions\n await checkPermission({\n credentials,\n permissions: [taskCancelPermission, taskReadPermission],\n permissionService: permissions,\n });\n\n const { taskId } = req.params;\n await taskBroker.cancel?.(taskId);\n res.status(200).json({ status: 'cancelled' });\n })\n .post('/v2/tasks/:taskId/retry', async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n // Requires both read and cancel permissions\n await checkPermission({\n credentials,\n permissions: [taskCreatePermission, taskReadPermission],\n permissionService: permissions,\n });\n\n const { taskId } = req.params;\n await taskBroker.retry?.(taskId);\n res.status(201).json({ id: taskId });\n })\n .get('/v2/tasks/:taskId/eventstream', async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n await checkPermission({\n credentials,\n permissions: [taskReadPermission],\n permissionService: permissions,\n });\n\n const { taskId } = req.params;\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: error => {\n logger.error(\n `Received error from event stream when observing taskId '${taskId}', ${error}`,\n );\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', () => {\n subscription.unsubscribe();\n logger.debug(`Event stream observing taskId '${taskId}' closed`);\n });\n })\n .get('/v2/tasks/:taskId/events', async (req, res) => {\n const credentials = await httpAuth.credentials(req);\n await checkPermission({\n credentials,\n permissions: [taskReadPermission],\n permissionService: permissions,\n });\n\n const { taskId } = req.params;\n const after = 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: error => {\n logger.error(\n `Received error from event stream when observing taskId '${taskId}', ${error}`,\n );\n },\n next: ({ events }) => {\n clearTimeout(timeout);\n subscription.unsubscribe();\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 })\n .post('/v2/dry-run', async (req, res) => {\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 { token } = await auth.getPluginRequestToken({\n onBehalfOf: credentials,\n targetPluginId: 'catalog',\n });\n\n const userEntityRef = auth.isPrincipal(credentials, 'user')\n ? credentials.principal.userEntityRef\n : undefined;\n\n const userEntity = userEntityRef\n ? await catalogClient.getEntityByRef(userEntityRef, { token })\n : undefined;\n\n for (const parameters of [template.spec.parameters ?? []].flat()) {\n const result = validate(body.values, parameters);\n if (!result.valid) {\n res.status(400).json({ errors: result.errors });\n return;\n }\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\n const templateInfo = {\n entityRef: stringifyEntityRef(template),\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 ...(token && { backstageToken: token }),\n },\n credentials,\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 })\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\n const app = express();\n app.set('logger', logger);\n app.use('/', router);\n\n async function authorizeTemplate(\n entityRef: CompoundEntityRef,\n token: string | undefined,\n credentials: BackstageCredentials,\n ) {\n const template = await findTemplate({\n catalogApi: catalogClient,\n entityRef,\n token,\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 isAuthorized(parameterDecision, step),\n );\n } else if (\n template.spec.parameters &&\n !isAuthorized(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 isAuthorized(stepDecision, step),\n );\n\n return template;\n }\n\n return app;\n}\n"],"names":["RESOURCE_TYPE_SCAFFOLDER_TEMPLATE","RESOURCE_TYPE_SCAFFOLDER_ACTION","parseEntityRef","stringifyError","config","readDurationFromConfig","Router","express","HostDiscovery","createLegacyAuthAdapters","getWorkingDirectory","ScmIntegrations","DatabaseTaskStore","StorageTaskBroker","Duration","TemplateActionRegistry","TaskWorker","createBuiltinActions","createDryRunner","scaffolderTemplateRules","scaffolderActionRules","createConditionAuthorizer","createPermissionIntegrationRouter","scaffolderTemplatePermissions","scaffolderActionPermissions","scaffolderTaskPermissions","checkPermission","taskCreatePermission","result","validate","getEntityBaseUrl","stringifyEntityRef","taskReadPermission","parseStringsParam","InputError","parseNumberParam","NotFoundError","taskCancelPermission","z","templateEntityV1beta3Validator","uuid","resolveSafeChildPath","pathToFileURL","findTemplate","templateParameterReadPermission","templateStepReadPermission"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var pluginPermissionNode = require('@backstage/plugin-permission-node');
|
|
4
4
|
var alpha = require('@backstage/plugin-scaffolder-common/alpha');
|
|
5
|
-
var
|
|
5
|
+
var z = require('zod');
|
|
6
6
|
var lodash = require('lodash');
|
|
7
7
|
|
|
8
8
|
const createTemplatePermissionRule = pluginPermissionNode.makeCreatePermissionRule();
|
|
@@ -10,8 +10,8 @@ const hasTag = createTemplatePermissionRule({
|
|
|
10
10
|
name: "HAS_TAG",
|
|
11
11
|
resourceType: alpha.RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,
|
|
12
12
|
description: `Match parameters or steps with the given tag`,
|
|
13
|
-
paramsSchema:
|
|
14
|
-
tag:
|
|
13
|
+
paramsSchema: z.z.object({
|
|
14
|
+
tag: z.z.string().describe("Name of the tag to match on")
|
|
15
15
|
}),
|
|
16
16
|
apply: (resource, { tag }) => {
|
|
17
17
|
return resource["backstage:permissions"]?.tags?.includes(tag) ?? false;
|
|
@@ -23,8 +23,8 @@ const hasActionId = createActionPermissionRule({
|
|
|
23
23
|
name: "HAS_ACTION_ID",
|
|
24
24
|
resourceType: alpha.RESOURCE_TYPE_SCAFFOLDER_ACTION,
|
|
25
25
|
description: `Match actions with the given actionId`,
|
|
26
|
-
paramsSchema:
|
|
27
|
-
actionId:
|
|
26
|
+
paramsSchema: z.z.object({
|
|
27
|
+
actionId: z.z.string().describe("Name of the actionId to match on")
|
|
28
28
|
}),
|
|
29
29
|
apply: (resource, { actionId }) => {
|
|
30
30
|
return resource.action === actionId;
|
|
@@ -33,20 +33,20 @@ const hasActionId = createActionPermissionRule({
|
|
|
33
33
|
});
|
|
34
34
|
buildHasProperty({
|
|
35
35
|
name: "HAS_PROPERTY",
|
|
36
|
-
valueSchema:
|
|
36
|
+
valueSchema: z.z.union([z.z.string(), z.z.number(), z.z.boolean(), z.z.null()]),
|
|
37
37
|
validateProperty: false
|
|
38
38
|
});
|
|
39
39
|
const hasBooleanProperty = buildHasProperty({
|
|
40
40
|
name: "HAS_BOOLEAN_PROPERTY",
|
|
41
|
-
valueSchema:
|
|
41
|
+
valueSchema: z.z.boolean()
|
|
42
42
|
});
|
|
43
43
|
const hasNumberProperty = buildHasProperty({
|
|
44
44
|
name: "HAS_NUMBER_PROPERTY",
|
|
45
|
-
valueSchema:
|
|
45
|
+
valueSchema: z.z.number()
|
|
46
46
|
});
|
|
47
47
|
const hasStringProperty = buildHasProperty({
|
|
48
48
|
name: "HAS_STRING_PROPERTY",
|
|
49
|
-
valueSchema:
|
|
49
|
+
valueSchema: z.z.string()
|
|
50
50
|
});
|
|
51
51
|
function buildHasProperty({
|
|
52
52
|
name,
|
|
@@ -57,8 +57,8 @@ function buildHasProperty({
|
|
|
57
57
|
name,
|
|
58
58
|
description: `Allow actions with the specified property`,
|
|
59
59
|
resourceType: alpha.RESOURCE_TYPE_SCAFFOLDER_ACTION,
|
|
60
|
-
paramsSchema:
|
|
61
|
-
key:
|
|
60
|
+
paramsSchema: z.z.object({
|
|
61
|
+
key: z.z.string().describe(`Property within the action parameters to match on`),
|
|
62
62
|
value: valueSchema.optional().describe(`Value of the given property to match on`)
|
|
63
63
|
}),
|
|
64
64
|
apply: (resource, { key, value }) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rules.cjs.js","sources":["../../src/service/rules.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 { makeCreatePermissionRule } from '@backstage/plugin-permission-node';\nimport {\n RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,\n RESOURCE_TYPE_SCAFFOLDER_ACTION,\n} from '@backstage/plugin-scaffolder-common/alpha';\n\nimport {\n TemplateEntityStepV1beta3,\n TemplateParametersV1beta3,\n} from '@backstage/plugin-scaffolder-common';\n\nimport { z } from 'zod';\nimport { JsonObject, JsonPrimitive } from '@backstage/types';\nimport { get } from 'lodash';\n\nexport const createTemplatePermissionRule = makeCreatePermissionRule<\n TemplateEntityStepV1beta3 | TemplateParametersV1beta3,\n {},\n typeof RESOURCE_TYPE_SCAFFOLDER_TEMPLATE\n>();\n\nexport const hasTag = createTemplatePermissionRule({\n name: 'HAS_TAG',\n resourceType: RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,\n description: `Match parameters or steps with the given tag`,\n paramsSchema: z.object({\n tag: z.string().describe('Name of the tag to match on'),\n }),\n apply: (resource, { tag }) => {\n return resource['backstage:permissions']?.tags?.includes(tag) ?? false;\n },\n toQuery: () => ({}),\n});\n\nexport const createActionPermissionRule = makeCreatePermissionRule<\n {\n action: string;\n input: JsonObject | undefined;\n },\n {},\n typeof RESOURCE_TYPE_SCAFFOLDER_ACTION\n>();\n\nexport const hasActionId = createActionPermissionRule({\n name: 'HAS_ACTION_ID',\n resourceType: RESOURCE_TYPE_SCAFFOLDER_ACTION,\n description: `Match actions with the given actionId`,\n paramsSchema: z.object({\n actionId: z.string().describe('Name of the actionId to match on'),\n }),\n apply: (resource, { actionId }) => {\n return resource.action === actionId;\n },\n toQuery: () => ({}),\n});\n\nexport const hasProperty = buildHasProperty({\n name: 'HAS_PROPERTY',\n valueSchema: z.union([z.string(), z.number(), z.boolean(), z.null()]),\n validateProperty: false,\n});\n\nexport const hasBooleanProperty = buildHasProperty({\n name: 'HAS_BOOLEAN_PROPERTY',\n valueSchema: z.boolean(),\n});\nexport const hasNumberProperty = buildHasProperty({\n name: 'HAS_NUMBER_PROPERTY',\n valueSchema: z.number(),\n});\nexport const hasStringProperty = buildHasProperty({\n name: 'HAS_STRING_PROPERTY',\n valueSchema: z.string(),\n});\n\nfunction buildHasProperty<Schema extends z.ZodType<JsonPrimitive>>({\n name,\n valueSchema,\n validateProperty = true,\n}: {\n name: string;\n valueSchema: Schema;\n validateProperty?: boolean;\n}) {\n return createActionPermissionRule({\n name,\n description: `Allow actions with the specified property`,\n resourceType: RESOURCE_TYPE_SCAFFOLDER_ACTION,\n paramsSchema: z.object({\n key: z\n .string()\n .describe(`Property within the action parameters to match on`),\n value: valueSchema\n .optional()\n .describe(`Value of the given property to match on`),\n }) as unknown as z.ZodType<{ key: string; value?: z.infer<Schema> }>,\n apply: (resource, { key, value }) => {\n const foundValue = get(resource.input, key);\n\n if (validateProperty && !valueSchema.safeParse(foundValue).success) {\n return false;\n }\n if (value !== undefined) {\n if (valueSchema.safeParse(value).success) {\n return value === foundValue;\n }\n return false;\n }\n\n return foundValue !== undefined;\n },\n toQuery: () => ({}),\n });\n}\n\nexport const scaffolderTemplateRules = { hasTag };\nexport const scaffolderActionRules = {\n hasActionId,\n hasBooleanProperty,\n hasNumberProperty,\n hasStringProperty,\n};\n"],"names":["makeCreatePermissionRule","RESOURCE_TYPE_SCAFFOLDER_TEMPLATE","z","RESOURCE_TYPE_SCAFFOLDER_ACTION","get"],"mappings":";;;;;;;AA+BO,MAAM,+BAA+BA,6CAI1C;AAEK,MAAM,SAAS,4BAA6B,CAAA;AAAA,EACjD,IAAM,EAAA,SAAA;AAAA,EACN,YAAc,EAAAC,uCAAA;AAAA,EACd,WAAa,EAAA,CAAA,4CAAA,CAAA;AAAA,EACb,YAAA,EAAcC,
|
|
1
|
+
{"version":3,"file":"rules.cjs.js","sources":["../../src/service/rules.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 { makeCreatePermissionRule } from '@backstage/plugin-permission-node';\nimport {\n RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,\n RESOURCE_TYPE_SCAFFOLDER_ACTION,\n} from '@backstage/plugin-scaffolder-common/alpha';\n\nimport {\n TemplateEntityStepV1beta3,\n TemplateParametersV1beta3,\n} from '@backstage/plugin-scaffolder-common';\n\nimport { z } from 'zod';\nimport { JsonObject, JsonPrimitive } from '@backstage/types';\nimport { get } from 'lodash';\n\nexport const createTemplatePermissionRule = makeCreatePermissionRule<\n TemplateEntityStepV1beta3 | TemplateParametersV1beta3,\n {},\n typeof RESOURCE_TYPE_SCAFFOLDER_TEMPLATE\n>();\n\nexport const hasTag = createTemplatePermissionRule({\n name: 'HAS_TAG',\n resourceType: RESOURCE_TYPE_SCAFFOLDER_TEMPLATE,\n description: `Match parameters or steps with the given tag`,\n paramsSchema: z.object({\n tag: z.string().describe('Name of the tag to match on'),\n }),\n apply: (resource, { tag }) => {\n return resource['backstage:permissions']?.tags?.includes(tag) ?? false;\n },\n toQuery: () => ({}),\n});\n\nexport const createActionPermissionRule = makeCreatePermissionRule<\n {\n action: string;\n input: JsonObject | undefined;\n },\n {},\n typeof RESOURCE_TYPE_SCAFFOLDER_ACTION\n>();\n\nexport const hasActionId = createActionPermissionRule({\n name: 'HAS_ACTION_ID',\n resourceType: RESOURCE_TYPE_SCAFFOLDER_ACTION,\n description: `Match actions with the given actionId`,\n paramsSchema: z.object({\n actionId: z.string().describe('Name of the actionId to match on'),\n }),\n apply: (resource, { actionId }) => {\n return resource.action === actionId;\n },\n toQuery: () => ({}),\n});\n\nexport const hasProperty = buildHasProperty({\n name: 'HAS_PROPERTY',\n valueSchema: z.union([z.string(), z.number(), z.boolean(), z.null()]),\n validateProperty: false,\n});\n\nexport const hasBooleanProperty = buildHasProperty({\n name: 'HAS_BOOLEAN_PROPERTY',\n valueSchema: z.boolean(),\n});\nexport const hasNumberProperty = buildHasProperty({\n name: 'HAS_NUMBER_PROPERTY',\n valueSchema: z.number(),\n});\nexport const hasStringProperty = buildHasProperty({\n name: 'HAS_STRING_PROPERTY',\n valueSchema: z.string(),\n});\n\nfunction buildHasProperty<Schema extends z.ZodType<JsonPrimitive>>({\n name,\n valueSchema,\n validateProperty = true,\n}: {\n name: string;\n valueSchema: Schema;\n validateProperty?: boolean;\n}) {\n return createActionPermissionRule({\n name,\n description: `Allow actions with the specified property`,\n resourceType: RESOURCE_TYPE_SCAFFOLDER_ACTION,\n paramsSchema: z.object({\n key: z\n .string()\n .describe(`Property within the action parameters to match on`),\n value: valueSchema\n .optional()\n .describe(`Value of the given property to match on`),\n }) as unknown as z.ZodType<{ key: string; value?: z.infer<Schema> }>,\n apply: (resource, { key, value }) => {\n const foundValue = get(resource.input, key);\n\n if (validateProperty && !valueSchema.safeParse(foundValue).success) {\n return false;\n }\n if (value !== undefined) {\n if (valueSchema.safeParse(value).success) {\n return value === foundValue;\n }\n return false;\n }\n\n return foundValue !== undefined;\n },\n toQuery: () => ({}),\n });\n}\n\nexport const scaffolderTemplateRules = { hasTag };\nexport const scaffolderActionRules = {\n hasActionId,\n hasBooleanProperty,\n hasNumberProperty,\n hasStringProperty,\n};\n"],"names":["makeCreatePermissionRule","RESOURCE_TYPE_SCAFFOLDER_TEMPLATE","z","RESOURCE_TYPE_SCAFFOLDER_ACTION","get"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@backstage/plugin-scaffolder-backend",
|
|
3
|
-
"version": "1.27.0-next.
|
|
3
|
+
"version": "1.27.0-next.3",
|
|
4
4
|
"description": "The Backstage backend plugin that helps you create new things",
|
|
5
5
|
"backstage": {
|
|
6
6
|
"role": "backend-plugin",
|
|
@@ -44,12 +44,21 @@
|
|
|
44
44
|
},
|
|
45
45
|
"main": "./dist/index.cjs.js",
|
|
46
46
|
"types": "./dist/index.d.ts",
|
|
47
|
+
"typesVersions": {
|
|
48
|
+
"*": {
|
|
49
|
+
"index": [
|
|
50
|
+
"dist/index.d.ts"
|
|
51
|
+
],
|
|
52
|
+
"alpha": [
|
|
53
|
+
"dist/alpha.d.ts"
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
},
|
|
47
57
|
"files": [
|
|
48
58
|
"dist",
|
|
49
59
|
"migrations",
|
|
50
60
|
"config.d.ts",
|
|
51
|
-
"assets"
|
|
52
|
-
"alpha"
|
|
61
|
+
"assets"
|
|
53
62
|
],
|
|
54
63
|
"scripts": {
|
|
55
64
|
"build": "backstage-cli package build",
|
|
@@ -63,7 +72,7 @@
|
|
|
63
72
|
},
|
|
64
73
|
"dependencies": {
|
|
65
74
|
"@backstage/backend-common": "^0.25.0",
|
|
66
|
-
"@backstage/backend-defaults": "0.5.3-next.
|
|
75
|
+
"@backstage/backend-defaults": "0.5.3-next.3",
|
|
67
76
|
"@backstage/backend-plugin-api": "1.0.2-next.2",
|
|
68
77
|
"@backstage/catalog-client": "1.8.0-next.1",
|
|
69
78
|
"@backstage/catalog-model": "1.7.0",
|
|
@@ -71,21 +80,21 @@
|
|
|
71
80
|
"@backstage/errors": "1.2.4",
|
|
72
81
|
"@backstage/integration": "1.15.1",
|
|
73
82
|
"@backstage/plugin-auth-node": "0.5.4-next.2",
|
|
74
|
-
"@backstage/plugin-bitbucket-cloud-common": "0.2.
|
|
75
|
-
"@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "0.2.2-next.
|
|
83
|
+
"@backstage/plugin-bitbucket-cloud-common": "0.2.25-next.0",
|
|
84
|
+
"@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "0.2.2-next.3",
|
|
76
85
|
"@backstage/plugin-catalog-node": "1.14.0-next.2",
|
|
77
86
|
"@backstage/plugin-permission-common": "0.8.1",
|
|
78
87
|
"@backstage/plugin-permission-node": "0.8.5-next.2",
|
|
79
|
-
"@backstage/plugin-scaffolder-backend-module-azure": "0.2.2-next.
|
|
80
|
-
"@backstage/plugin-scaffolder-backend-module-bitbucket": "0.3.2-next.
|
|
81
|
-
"@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": "0.2.2-next.
|
|
82
|
-
"@backstage/plugin-scaffolder-backend-module-bitbucket-server": "0.2.2-next.
|
|
83
|
-
"@backstage/plugin-scaffolder-backend-module-gerrit": "0.2.2-next.
|
|
84
|
-
"@backstage/plugin-scaffolder-backend-module-gitea": "0.2.2-next.
|
|
85
|
-
"@backstage/plugin-scaffolder-backend-module-github": "0.5.2-next.
|
|
86
|
-
"@backstage/plugin-scaffolder-backend-module-gitlab": "0.6.1-next.
|
|
87
|
-
"@backstage/plugin-scaffolder-common": "1.5.
|
|
88
|
-
"@backstage/plugin-scaffolder-node": "0.5.1-next.
|
|
88
|
+
"@backstage/plugin-scaffolder-backend-module-azure": "0.2.2-next.3",
|
|
89
|
+
"@backstage/plugin-scaffolder-backend-module-bitbucket": "0.3.2-next.3",
|
|
90
|
+
"@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": "0.2.2-next.3",
|
|
91
|
+
"@backstage/plugin-scaffolder-backend-module-bitbucket-server": "0.2.2-next.3",
|
|
92
|
+
"@backstage/plugin-scaffolder-backend-module-gerrit": "0.2.2-next.3",
|
|
93
|
+
"@backstage/plugin-scaffolder-backend-module-gitea": "0.2.2-next.3",
|
|
94
|
+
"@backstage/plugin-scaffolder-backend-module-github": "0.5.2-next.3",
|
|
95
|
+
"@backstage/plugin-scaffolder-backend-module-gitlab": "0.6.1-next.3",
|
|
96
|
+
"@backstage/plugin-scaffolder-common": "1.5.7-next.0",
|
|
97
|
+
"@backstage/plugin-scaffolder-node": "0.5.1-next.3",
|
|
89
98
|
"@backstage/types": "1.1.1",
|
|
90
99
|
"@opentelemetry/api": "^1.3.0",
|
|
91
100
|
"@types/express": "^4.17.6",
|
|
@@ -117,10 +126,10 @@
|
|
|
117
126
|
},
|
|
118
127
|
"devDependencies": {
|
|
119
128
|
"@backstage/backend-app-api": "1.0.2-next.2",
|
|
120
|
-
"@backstage/backend-defaults": "0.5.3-next.
|
|
121
|
-
"@backstage/backend-test-utils": "1.1.0-next.
|
|
122
|
-
"@backstage/cli": "0.29.0-next.
|
|
123
|
-
"@backstage/plugin-scaffolder-node-test-utils": "0.1.15-next.
|
|
129
|
+
"@backstage/backend-defaults": "0.5.3-next.3",
|
|
130
|
+
"@backstage/backend-test-utils": "1.1.0-next.3",
|
|
131
|
+
"@backstage/cli": "0.29.0-next.3",
|
|
132
|
+
"@backstage/plugin-scaffolder-node-test-utils": "0.1.15-next.3",
|
|
124
133
|
"@types/fs-extra": "^11.0.0",
|
|
125
134
|
"@types/nunjucks": "^3.1.4",
|
|
126
135
|
"@types/supertest": "^2.0.8",
|