@red-hat-developer-hub/backstage-plugin-scaffolder-backend-module-orchestrator 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # @red-hat-developer-hub/backstage-plugin-scaffolder-backend-module-orchestrator
2
+
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - ebf64b9: Added yarn export-dynamic target
package/README.md ADDED
@@ -0,0 +1,93 @@
1
+ # backstage-plugin-scaffolder-backend-module-orchestrator
2
+
3
+ The Orchestrator module [@backstage/plugin-scaffolder-backend](https://www.npmjs.com/package/@backstage/plugin-scaffolder-backend) provides actions callable from the [Backstage templates](https://backstage.io/docs/features/software-templates/).
4
+
5
+ An example of using these actions can be found in the `workspaces/orchestrator/entities/convertWorkflowToTemplate.yaml` template.
6
+
7
+ ## Installation
8
+
9
+ ### As a static plugin
10
+
11
+ In `packages/backend/src/index.ts`:
12
+
13
+ ```
14
+ backend.add(import('@red-hat-developer-hub/backstage-plugin-scaffolder-backend-module-orchestrator'));
15
+ ```
16
+
17
+ # The software template generating templates from workflows - convertWorkflowToTemplate
18
+
19
+ The `workspaces/orchestrator/entities/convertWorkflowToTemplate.yaml` scaffolder software template is used for generating templates to be used to execute a serverless workflow via the Orchestrator.
20
+
21
+ The generated template is a yaml document which is pushed to a GitHub repository for later consumption by the Backstage.
22
+
23
+ The only specific input parameter is the `workflowId` of the desired workflow.
24
+
25
+ The rest of parameters cover details about the target GitHub repository to either create a new repo or push a PR to an existing one.
26
+
27
+ The generated yaml template is accompanied by a README file highlighting instructions how to register the new template in the Backstage catalog.
28
+
29
+ ## Important Note on Template Input Structure
30
+
31
+ The structure of the template input differs from that of the page used for collecting input parameters for workflows, despite some similarities. These two pages are supported by distinct implementations. While the set of parameters should remain consistent, their visual representation and especially grouping into steps may vary.
32
+
33
+ ## What is a workflow ID
34
+
35
+ The `[workflowId]` matches the identifier from the workflow definition.
36
+ For example, in the [workflow definition](https://github.com/rhdhorchestrator/serverless-workflows/blob/main/workflows/greeting/greeting.sw.yaml) below, the identifier is `greeting`:
37
+
38
+ ```yaml greeting.sw.yaml
39
+ id: greeting
40
+ version: '1.0'
41
+ specVersion: '0.8'
42
+ name: Greeting workflow
43
+ description: YAML based greeting workflow
44
+ annotations:
45
+ - 'workflow-type/infrastructure'
46
+ dataInputSchema: 'schemas/greeting.sw.input-schema.json'
47
+ extensions:
48
+ - extensionid: workflow-output-schema
49
+ outputSchema: schemas/workflow-output-schema.json
50
+ ```
51
+
52
+ ## GitHub integration
53
+
54
+ The `convertWorkflowToTemplate.yaml` template pushes the result into a GitHub repository.
55
+ To make it work, the [Backstage integration with GitHub](https://backstage.io/docs/integrations/github/locations) needs to be properly set.
56
+
57
+ In a nutshell:
58
+
59
+ - add `@backstage/plugin-scaffolder-backend-module-github` to your `backend` application, sort of:
60
+
61
+ ```bash
62
+ yarn --cwd packages/backend add @backstage/plugin-scaffolder-backend-module-github
63
+ ```
64
+
65
+ - in `packages/backend/src/index.ts`:
66
+
67
+ ```
68
+ backend.add(import('@backstage/plugin-scaffolder-backend-module-github'));
69
+ ```
70
+
71
+ - generate GitHub access token, e.g. via https://github.com/settings/personal-access-tokens and set
72
+
73
+ ```bash
74
+ export GITHUB_TOKEN=.......
75
+ ```
76
+
77
+ - configure `app-config.yaml`:
78
+
79
+ ```
80
+ integrations:
81
+ github:
82
+ - token: ${GITHUB_TOKEN}
83
+ ```
84
+
85
+ ## Resources
86
+
87
+ - [Upstream documentation](https://backstage.io/docs/features/software-templates/builtin-actions)
88
+
89
+ # Hints
90
+
91
+ Mind using `export NODE_OPTIONS="${NODE_OPTIONS:-} --no-node-snapshot"` before running the Backstage backend app with Node 20+ (per actual [warning in the upstream documentation](https://backstage.io/docs/features/software-templates/#getting-started)) - this might be changed in the future.
92
+
93
+ Before running the Backstage backend app with **Node 20+**, be sure to execute `export NODE_OPTIONS="${NODE_OPTIONS:-} --no-node-snapshot` as recommended by the [warning in the upstream documentation](https://backstage.io/docs/features/software-templates/#getting-started) (this might be changed in the future).
@@ -0,0 +1,77 @@
1
+ 'use strict';
2
+
3
+ var pluginScaffolderNode = require('@backstage/plugin-scaffolder-node');
4
+ var axios = require('axios');
5
+ var jsYaml = require('js-yaml');
6
+ var utils = require('./utils.cjs.js');
7
+
8
+ const getError = (err) => {
9
+ if (axios.isAxiosError(err) && err.response?.data?.error?.message) {
10
+ const error = new Error(err.response?.data?.error?.message);
11
+ error.name = err.response?.data?.error?.name || "Error";
12
+ return error;
13
+ }
14
+ return err;
15
+ };
16
+ const indentString = (str, indent) => indent ? str.replace(/^/gm, " ".repeat(indent)) : str;
17
+ const createGetWorkflowParamsAction = (discoveryService, authService) => pluginScaffolderNode.createTemplateAction({
18
+ id: "orchestrator:workflow:get_params",
19
+ description: "Collect parameters of a SonataFlow workflow.",
20
+ supportsDryRun: false,
21
+ schema: {
22
+ input: {
23
+ required: ["workflow_id"],
24
+ type: "object",
25
+ properties: {
26
+ workflow_id: {
27
+ type: "string"
28
+ }
29
+ }
30
+ }
31
+ },
32
+ async handler(ctx) {
33
+ const workflowId = ctx.input?.workflow_id;
34
+ if (!workflowId) {
35
+ throw new Error("Missing workflow_id required input parameter.");
36
+ }
37
+ const api = await utils.getOrchestratorApi(discoveryService);
38
+ const reqConfigOption = await utils.getRequestConfigOption(authService, ctx);
39
+ try {
40
+ const { data: workflow } = await api.getWorkflowOverviewById(
41
+ workflowId,
42
+ reqConfigOption
43
+ );
44
+ if (!workflow) {
45
+ throw new Error(`Can not find workflow ${workflowId}`);
46
+ }
47
+ const { data: inputSchemaWrapper } = await api.getWorkflowInputSchemaById(
48
+ workflowId,
49
+ void 0,
50
+ reqConfigOption
51
+ );
52
+ const inputSchema = inputSchemaWrapper.inputSchema;
53
+ ctx.output("title", workflow.name || workflowId);
54
+ ctx.output("description", workflow.description || "");
55
+ if (inputSchema?.properties) {
56
+ let parametersYaml = jsYaml.dump(
57
+ [
58
+ // scaffolder expects an array on the top-level
59
+ inputSchema
60
+ ],
61
+ { indent: 2 }
62
+ );
63
+ parametersYaml = indentString(parametersYaml, ctx.input?.indent || 0);
64
+ parametersYaml = `
65
+ ${parametersYaml}`;
66
+ ctx.output("parameters", parametersYaml);
67
+ } else {
68
+ ctx.output("parameters", "{}");
69
+ }
70
+ } catch (err) {
71
+ throw getError(err);
72
+ }
73
+ }
74
+ });
75
+
76
+ exports.createGetWorkflowParamsAction = createGetWorkflowParamsAction;
77
+ //# sourceMappingURL=getWorkflowParams.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getWorkflowParams.cjs.js","sources":["../../src/actions/getWorkflowParams.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 { AuthService } from '@backstage/backend-plugin-api';\nimport { DiscoveryApi } from '@backstage/plugin-permission-common/index';\nimport { createTemplateAction } from '@backstage/plugin-scaffolder-node';\nimport { JsonObject } from '@backstage/types/index';\n\nimport { isAxiosError } from 'axios';\nimport { dump } from 'js-yaml';\n\nimport { getOrchestratorApi, getRequestConfigOption } from './utils';\n\ntype RunWorkflowTemplateActionInput = { workflow_id: string; indent?: number };\ntype RunWorkflowTemplateActionOutput = {\n title: string;\n description: string;\n parameters: string;\n};\n\nconst getError = (err: unknown): Error => {\n if (\n isAxiosError<{ error: { message: string; name: string } }>(err) &&\n err.response?.data?.error?.message\n ) {\n const error = new Error(err.response?.data?.error?.message);\n error.name = err.response?.data?.error?.name || 'Error';\n return error;\n }\n return err as Error;\n};\n\nconst indentString = (str: string, indent: number) =>\n indent ? str.replace(/^/gm, ' '.repeat(indent)) : str;\n\nexport const createGetWorkflowParamsAction = (\n discoveryService: DiscoveryApi,\n authService: AuthService,\n) =>\n createTemplateAction<\n RunWorkflowTemplateActionInput,\n RunWorkflowTemplateActionOutput\n >({\n id: 'orchestrator:workflow:get_params',\n description: 'Collect parameters of a SonataFlow workflow.',\n supportsDryRun: false,\n schema: {\n input: {\n required: ['workflow_id'],\n type: 'object',\n properties: {\n workflow_id: {\n type: 'string',\n },\n },\n },\n },\n async handler(ctx) {\n const workflowId = ctx.input?.workflow_id;\n if (!workflowId) {\n throw new Error('Missing workflow_id required input parameter.');\n }\n\n const api = await getOrchestratorApi(discoveryService);\n const reqConfigOption = await getRequestConfigOption(authService, ctx);\n\n try {\n const { data: workflow } = await api.getWorkflowOverviewById(\n workflowId,\n reqConfigOption,\n );\n if (!workflow) {\n throw new Error(`Can not find workflow ${workflowId}`);\n }\n\n const { data: inputSchemaWrapper } =\n await api.getWorkflowInputSchemaById(\n workflowId,\n undefined,\n reqConfigOption,\n );\n const inputSchema: JsonObject | undefined =\n inputSchemaWrapper.inputSchema;\n\n ctx.output('title', workflow.name || workflowId);\n ctx.output('description', workflow.description || '');\n\n if (inputSchema?.properties) {\n let parametersYaml = dump(\n [\n // scaffolder expects an array on the top-level\n inputSchema,\n ],\n { indent: 2 },\n );\n parametersYaml = indentString(parametersYaml, ctx.input?.indent || 0);\n parametersYaml = `\\n${parametersYaml}`;\n\n ctx.output('parameters', parametersYaml);\n } else {\n ctx.output('parameters', '{}');\n }\n } catch (err) {\n throw getError(err);\n }\n },\n });\n"],"names":["isAxiosError","createTemplateAction","getOrchestratorApi","getRequestConfigOption","dump"],"mappings":";;;;;;;AAgCA,MAAM,QAAA,GAAW,CAAC,GAAwB,KAAA;AACxC,EAAA,IACEA,mBAA2D,GAAG,CAAA,IAC9D,IAAI,QAAU,EAAA,IAAA,EAAM,OAAO,OAC3B,EAAA;AACA,IAAA,MAAM,QAAQ,IAAI,KAAA,CAAM,IAAI,QAAU,EAAA,IAAA,EAAM,OAAO,OAAO,CAAA;AAC1D,IAAA,KAAA,CAAM,IAAO,GAAA,GAAA,CAAI,QAAU,EAAA,IAAA,EAAM,OAAO,IAAQ,IAAA,OAAA;AAChD,IAAO,OAAA,KAAA;AAAA;AAET,EAAO,OAAA,GAAA;AACT,CAAA;AAEA,MAAM,YAAe,GAAA,CAAC,GAAa,EAAA,MAAA,KACjC,MAAS,GAAA,GAAA,CAAI,OAAQ,CAAA,KAAA,EAAO,GAAI,CAAA,MAAA,CAAO,MAAM,CAAC,CAAI,GAAA,GAAA;AAE7C,MAAM,6BAAgC,GAAA,CAC3C,gBACA,EAAA,WAAA,KAEAC,yCAGE,CAAA;AAAA,EACA,EAAI,EAAA,kCAAA;AAAA,EACJ,WAAa,EAAA,8CAAA;AAAA,EACb,cAAgB,EAAA,KAAA;AAAA,EAChB,MAAQ,EAAA;AAAA,IACN,KAAO,EAAA;AAAA,MACL,QAAA,EAAU,CAAC,aAAa,CAAA;AAAA,MACxB,IAAM,EAAA,QAAA;AAAA,MACN,UAAY,EAAA;AAAA,QACV,WAAa,EAAA;AAAA,UACX,IAAM,EAAA;AAAA;AACR;AACF;AACF,GACF;AAAA,EACA,MAAM,QAAQ,GAAK,EAAA;AACjB,IAAM,MAAA,UAAA,GAAa,IAAI,KAAO,EAAA,WAAA;AAC9B,IAAA,IAAI,CAAC,UAAY,EAAA;AACf,MAAM,MAAA,IAAI,MAAM,+CAA+C,CAAA;AAAA;AAGjE,IAAM,MAAA,GAAA,GAAM,MAAMC,wBAAA,CAAmB,gBAAgB,CAAA;AACrD,IAAA,MAAM,eAAkB,GAAA,MAAMC,4BAAuB,CAAA,WAAA,EAAa,GAAG,CAAA;AAErE,IAAI,IAAA;AACF,MAAA,MAAM,EAAE,IAAA,EAAM,QAAS,EAAA,GAAI,MAAM,GAAI,CAAA,uBAAA;AAAA,QACnC,UAAA;AAAA,QACA;AAAA,OACF;AACA,MAAA,IAAI,CAAC,QAAU,EAAA;AACb,QAAA,MAAM,IAAI,KAAA,CAAM,CAAyB,sBAAA,EAAA,UAAU,CAAE,CAAA,CAAA;AAAA;AAGvD,MAAA,MAAM,EAAE,IAAA,EAAM,kBAAmB,EAAA,GAC/B,MAAM,GAAI,CAAA,0BAAA;AAAA,QACR,UAAA;AAAA,QACA,KAAA,CAAA;AAAA,QACA;AAAA,OACF;AACF,MAAA,MAAM,cACJ,kBAAmB,CAAA,WAAA;AAErB,MAAA,GAAA,CAAI,MAAO,CAAA,OAAA,EAAS,QAAS,CAAA,IAAA,IAAQ,UAAU,CAAA;AAC/C,MAAA,GAAA,CAAI,MAAO,CAAA,aAAA,EAAe,QAAS,CAAA,WAAA,IAAe,EAAE,CAAA;AAEpD,MAAA,IAAI,aAAa,UAAY,EAAA;AAC3B,QAAA,IAAI,cAAiB,GAAAC,WAAA;AAAA,UACnB;AAAA;AAAA,YAEE;AAAA,WACF;AAAA,UACA,EAAE,QAAQ,CAAE;AAAA,SACd;AACA,QAAA,cAAA,GAAiB,YAAa,CAAA,cAAA,EAAgB,GAAI,CAAA,KAAA,EAAO,UAAU,CAAC,CAAA;AACpE,QAAiB,cAAA,GAAA;AAAA,EAAK,cAAc,CAAA,CAAA;AAEpC,QAAI,GAAA,CAAA,MAAA,CAAO,cAAc,cAAc,CAAA;AAAA,OAClC,MAAA;AACL,QAAI,GAAA,CAAA,MAAA,CAAO,cAAc,IAAI,CAAA;AAAA;AAC/B,aACO,GAAK,EAAA;AACZ,MAAA,MAAM,SAAS,GAAG,CAAA;AAAA;AACpB;AAEJ,CAAC;;;;"}
@@ -0,0 +1,59 @@
1
+ 'use strict';
2
+
3
+ var catalogModel = require('@backstage/catalog-model');
4
+ var pluginScaffolderNode = require('@backstage/plugin-scaffolder-node');
5
+ var axios = require('axios');
6
+ var utils = require('./utils.cjs.js');
7
+
8
+ const getError = (err) => {
9
+ if (axios.isAxiosError(err) && err.response?.data?.error?.message) {
10
+ const error = new Error(err.response?.data?.error?.message);
11
+ error.name = err.response?.data?.error?.name || "Error";
12
+ return error;
13
+ }
14
+ return err;
15
+ };
16
+ const createRunWorkflowAction = (discoveryService, authService) => pluginScaffolderNode.createTemplateAction({
17
+ id: "orchestrator:workflow:run",
18
+ description: "Run a SonataFlow workflow.",
19
+ supportsDryRun: true,
20
+ schema: {
21
+ input: {
22
+ required: ["parameters"],
23
+ type: "object",
24
+ properties: {
25
+ parameters: {
26
+ type: "object",
27
+ title: "Parameters",
28
+ description: "The workflow parameters."
29
+ }
30
+ }
31
+ }
32
+ },
33
+ async handler(ctx) {
34
+ const entity = ctx.templateInfo?.entityRef;
35
+ if (!entity) {
36
+ throw new Error("No template entity");
37
+ }
38
+ const api = await utils.getOrchestratorApi(discoveryService);
39
+ const reqConfigOption = await utils.getRequestConfigOption(authService, ctx);
40
+ if (ctx.isDryRun) {
41
+ ctx.logger.info(`Dry run complete`);
42
+ return;
43
+ }
44
+ try {
45
+ const { data } = await api.executeWorkflow(
46
+ catalogModel.parseEntityRef(entity).name,
47
+ { inputData: ctx.input.parameters },
48
+ void 0,
49
+ reqConfigOption
50
+ );
51
+ ctx.output("instanceUrl", `/orchestrator/instances/${data.id}`);
52
+ } catch (err) {
53
+ throw getError(err);
54
+ }
55
+ }
56
+ });
57
+
58
+ exports.createRunWorkflowAction = createRunWorkflowAction;
59
+ //# sourceMappingURL=runWorkflow.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runWorkflow.cjs.js","sources":["../../src/actions/runWorkflow.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 { AuthService } from '@backstage/backend-plugin-api';\nimport { parseEntityRef } from '@backstage/catalog-model';\nimport { DiscoveryApi } from '@backstage/plugin-permission-common/index';\nimport { createTemplateAction } from '@backstage/plugin-scaffolder-node';\nimport { JsonObject } from '@backstage/types';\n\nimport { isAxiosError } from 'axios';\n\nimport { getOrchestratorApi, getRequestConfigOption } from './utils';\n\ntype RunWorkflowTemplateActionInput = { parameters: JsonObject };\ntype RunWorkflowTemplateActionOutput = { instanceUrl: string };\n\nconst getError = (err: unknown): Error => {\n if (\n isAxiosError<{ error: { message: string; name: string } }>(err) &&\n err.response?.data?.error?.message\n ) {\n const error = new Error(err.response?.data?.error?.message);\n error.name = err.response?.data?.error?.name || 'Error';\n return error;\n }\n return err as Error;\n};\n\nexport const createRunWorkflowAction = (\n discoveryService: DiscoveryApi,\n authService: AuthService,\n) =>\n createTemplateAction<\n RunWorkflowTemplateActionInput,\n RunWorkflowTemplateActionOutput\n >({\n id: 'orchestrator:workflow:run',\n description: 'Run a SonataFlow workflow.',\n supportsDryRun: true,\n schema: {\n input: {\n required: ['parameters'],\n type: 'object',\n properties: {\n parameters: {\n type: 'object',\n title: 'Parameters',\n description: 'The workflow parameters.',\n },\n },\n },\n },\n async handler(ctx) {\n const entity = ctx.templateInfo?.entityRef;\n if (!entity) {\n throw new Error('No template entity');\n }\n\n const api = await getOrchestratorApi(discoveryService);\n const reqConfigOption = await getRequestConfigOption(authService, ctx);\n\n // If this is a dry run, log and return\n if (ctx.isDryRun) {\n ctx.logger.info(`Dry run complete`);\n return;\n }\n\n try {\n const { data } = await api.executeWorkflow(\n parseEntityRef(entity).name,\n { inputData: ctx.input.parameters },\n undefined,\n reqConfigOption,\n );\n ctx.output('instanceUrl', `/orchestrator/instances/${data.id}`);\n } catch (err) {\n throw getError(err);\n }\n },\n });\n"],"names":["isAxiosError","createTemplateAction","getOrchestratorApi","getRequestConfigOption","parseEntityRef"],"mappings":";;;;;;;AA4BA,MAAM,QAAA,GAAW,CAAC,GAAwB,KAAA;AACxC,EAAA,IACEA,mBAA2D,GAAG,CAAA,IAC9D,IAAI,QAAU,EAAA,IAAA,EAAM,OAAO,OAC3B,EAAA;AACA,IAAA,MAAM,QAAQ,IAAI,KAAA,CAAM,IAAI,QAAU,EAAA,IAAA,EAAM,OAAO,OAAO,CAAA;AAC1D,IAAA,KAAA,CAAM,IAAO,GAAA,GAAA,CAAI,QAAU,EAAA,IAAA,EAAM,OAAO,IAAQ,IAAA,OAAA;AAChD,IAAO,OAAA,KAAA;AAAA;AAET,EAAO,OAAA,GAAA;AACT,CAAA;AAEO,MAAM,uBAA0B,GAAA,CACrC,gBACA,EAAA,WAAA,KAEAC,yCAGE,CAAA;AAAA,EACA,EAAI,EAAA,2BAAA;AAAA,EACJ,WAAa,EAAA,4BAAA;AAAA,EACb,cAAgB,EAAA,IAAA;AAAA,EAChB,MAAQ,EAAA;AAAA,IACN,KAAO,EAAA;AAAA,MACL,QAAA,EAAU,CAAC,YAAY,CAAA;AAAA,MACvB,IAAM,EAAA,QAAA;AAAA,MACN,UAAY,EAAA;AAAA,QACV,UAAY,EAAA;AAAA,UACV,IAAM,EAAA,QAAA;AAAA,UACN,KAAO,EAAA,YAAA;AAAA,UACP,WAAa,EAAA;AAAA;AACf;AACF;AACF,GACF;AAAA,EACA,MAAM,QAAQ,GAAK,EAAA;AACjB,IAAM,MAAA,MAAA,GAAS,IAAI,YAAc,EAAA,SAAA;AACjC,IAAA,IAAI,CAAC,MAAQ,EAAA;AACX,MAAM,MAAA,IAAI,MAAM,oBAAoB,CAAA;AAAA;AAGtC,IAAM,MAAA,GAAA,GAAM,MAAMC,wBAAA,CAAmB,gBAAgB,CAAA;AACrD,IAAA,MAAM,eAAkB,GAAA,MAAMC,4BAAuB,CAAA,WAAA,EAAa,GAAG,CAAA;AAGrE,IAAA,IAAI,IAAI,QAAU,EAAA;AAChB,MAAI,GAAA,CAAA,MAAA,CAAO,KAAK,CAAkB,gBAAA,CAAA,CAAA;AAClC,MAAA;AAAA;AAGF,IAAI,IAAA;AACF,MAAA,MAAM,EAAE,IAAA,EAAS,GAAA,MAAM,GAAI,CAAA,eAAA;AAAA,QACzBC,2BAAA,CAAe,MAAM,CAAE,CAAA,IAAA;AAAA,QACvB,EAAE,SAAA,EAAW,GAAI,CAAA,KAAA,CAAM,UAAW,EAAA;AAAA,QAClC,KAAA,CAAA;AAAA,QACA;AAAA,OACF;AACA,MAAA,GAAA,CAAI,MAAO,CAAA,aAAA,EAAe,CAA2B,wBAAA,EAAA,IAAA,CAAK,EAAE,CAAE,CAAA,CAAA;AAAA,aACvD,GAAK,EAAA;AACZ,MAAA,MAAM,SAAS,GAAG,CAAA;AAAA;AACpB;AAEJ,CAAC;;;;"}
@@ -0,0 +1,34 @@
1
+ 'use strict';
2
+
3
+ var axios = require('axios');
4
+ var backstagePluginOrchestratorCommon = require('@red-hat-developer-hub/backstage-plugin-orchestrator-common');
5
+
6
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
7
+
8
+ var axios__default = /*#__PURE__*/_interopDefaultCompat(axios);
9
+
10
+ const getOrchestratorApi = async (discoveryService) => {
11
+ const baseUrl = await discoveryService.getBaseUrl("orchestrator");
12
+ const config = new backstagePluginOrchestratorCommon.Configuration({});
13
+ const axiosInstance = axios__default.default.create({
14
+ baseURL: baseUrl
15
+ });
16
+ const api = new backstagePluginOrchestratorCommon.DefaultApi(config, baseUrl, axiosInstance);
17
+ return api;
18
+ };
19
+ const getRequestConfigOption = async (authService, ctx) => {
20
+ const { token } = await authService.getPluginRequestToken({
21
+ onBehalfOf: await ctx.getInitiatorCredentials(),
22
+ targetPluginId: "orchestrator"
23
+ }) ?? { token: ctx.secrets?.backstageToken };
24
+ const reqConfigOption = {
25
+ headers: {
26
+ Authorization: `Bearer ${token}`
27
+ }
28
+ };
29
+ return reqConfigOption;
30
+ };
31
+
32
+ exports.getOrchestratorApi = getOrchestratorApi;
33
+ exports.getRequestConfigOption = getRequestConfigOption;
34
+ //# sourceMappingURL=utils.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.cjs.js","sources":["../../src/actions/utils.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\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 { AuthService } from '@backstage/backend-plugin-api';\nimport { DiscoveryApi } from '@backstage/plugin-permission-common/index';\n\nimport axios, { AxiosRequestConfig, isAxiosError } from 'axios';\n\nimport {\n Configuration,\n DefaultApi,\n} from '@red-hat-developer-hub/backstage-plugin-orchestrator-common';\n\nexport const getError = (err: unknown): Error => {\n if (\n isAxiosError<{ error: { message: string; name: string } }>(err) &&\n err.response?.data?.error?.message\n ) {\n const error = new Error(err.response?.data?.error?.message);\n error.name = err.response?.data?.error?.name || 'Error';\n return error;\n }\n return err as Error;\n};\n\nexport const getOrchestratorApi = async (\n discoveryService: DiscoveryApi,\n): Promise<DefaultApi> => {\n const baseUrl = await discoveryService.getBaseUrl('orchestrator');\n const config = new Configuration({});\n\n const axiosInstance = axios.create({\n baseURL: baseUrl,\n });\n const api = new DefaultApi(config, baseUrl, axiosInstance);\n\n return api;\n};\nexport const getRequestConfigOption = async (\n authService: AuthService,\n ctx: any,\n) => {\n const { token } = (await authService.getPluginRequestToken({\n onBehalfOf: await ctx.getInitiatorCredentials(),\n targetPluginId: 'orchestrator',\n })) ?? { token: ctx.secrets?.backstageToken };\n\n const reqConfigOption: AxiosRequestConfig = {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n };\n\n return reqConfigOption;\n};\n"],"names":["Configuration","axios","DefaultApi"],"mappings":";;;;;;;;;AAqCa,MAAA,kBAAA,GAAqB,OAChC,gBACwB,KAAA;AACxB,EAAA,MAAM,OAAU,GAAA,MAAM,gBAAiB,CAAA,UAAA,CAAW,cAAc,CAAA;AAChE,EAAA,MAAM,MAAS,GAAA,IAAIA,+CAAc,CAAA,EAAE,CAAA;AAEnC,EAAM,MAAA,aAAA,GAAgBC,uBAAM,MAAO,CAAA;AAAA,IACjC,OAAS,EAAA;AAAA,GACV,CAAA;AACD,EAAA,MAAM,GAAM,GAAA,IAAIC,4CAAW,CAAA,MAAA,EAAQ,SAAS,aAAa,CAAA;AAEzD,EAAO,OAAA,GAAA;AACT;AACa,MAAA,sBAAA,GAAyB,OACpC,WAAA,EACA,GACG,KAAA;AACH,EAAA,MAAM,EAAE,KAAA,EAAW,GAAA,MAAM,YAAY,qBAAsB,CAAA;AAAA,IACzD,UAAA,EAAY,MAAM,GAAA,CAAI,uBAAwB,EAAA;AAAA,IAC9C,cAAgB,EAAA;AAAA,GACjB,CAAM,IAAA,EAAE,KAAO,EAAA,GAAA,CAAI,SAAS,cAAe,EAAA;AAE5C,EAAA,MAAM,eAAsC,GAAA;AAAA,IAC1C,OAAS,EAAA;AAAA,MACP,aAAA,EAAe,UAAU,KAAK,CAAA;AAAA;AAChC,GACF;AAEA,EAAO,OAAA,eAAA;AACT;;;;;"}
@@ -0,0 +1,10 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var module$1 = require('./module.cjs.js');
6
+
7
+
8
+
9
+ exports.default = module$1.scaffolderModule;
10
+ //# sourceMappingURL=index.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
@@ -0,0 +1,8 @@
1
+ import * as _backstage_backend_plugin_api from '@backstage/backend-plugin-api';
2
+
3
+ /**
4
+ * A backend module that registers the action into the scaffolder
5
+ */
6
+ declare const scaffolderModule: _backstage_backend_plugin_api.BackendFeature;
7
+
8
+ export { scaffolderModule as default };
@@ -0,0 +1,31 @@
1
+ 'use strict';
2
+
3
+ var backendPluginApi = require('@backstage/backend-plugin-api');
4
+ var alpha = require('@backstage/plugin-scaffolder-node/alpha');
5
+ var runWorkflow = require('./actions/runWorkflow.cjs.js');
6
+ var getWorkflowParams = require('./actions/getWorkflowParams.cjs.js');
7
+
8
+ const scaffolderModule = backendPluginApi.createBackendModule({
9
+ moduleId: "orchestrator",
10
+ pluginId: "scaffolder",
11
+ register({ registerInit }) {
12
+ registerInit({
13
+ deps: {
14
+ scaffolderActions: alpha.scaffolderActionsExtensionPoint,
15
+ discoveryService: backendPluginApi.coreServices.discovery,
16
+ authService: backendPluginApi.coreServices.auth
17
+ },
18
+ async init({ scaffolderActions, discoveryService, authService }) {
19
+ scaffolderActions.addActions(
20
+ runWorkflow.createRunWorkflowAction(discoveryService, authService)
21
+ );
22
+ scaffolderActions.addActions(
23
+ getWorkflowParams.createGetWorkflowParamsAction(discoveryService, authService)
24
+ );
25
+ }
26
+ });
27
+ }
28
+ });
29
+
30
+ exports.scaffolderModule = scaffolderModule;
31
+ //# sourceMappingURL=module.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module.cjs.js","sources":["../src/module.ts"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n coreServices,\n createBackendModule,\n} from '@backstage/backend-plugin-api';\nimport { scaffolderActionsExtensionPoint } from '@backstage/plugin-scaffolder-node/alpha';\n\nimport {\n createGetWorkflowParamsAction,\n createRunWorkflowAction,\n} from './actions';\n\n/**\n * A backend module that registers the action into the scaffolder\n */\nexport const scaffolderModule = createBackendModule({\n moduleId: 'orchestrator',\n pluginId: 'scaffolder',\n register({ registerInit }) {\n registerInit({\n deps: {\n scaffolderActions: scaffolderActionsExtensionPoint,\n discoveryService: coreServices.discovery,\n authService: coreServices.auth,\n },\n async init({ scaffolderActions, discoveryService, authService }) {\n scaffolderActions.addActions(\n createRunWorkflowAction(discoveryService, authService),\n );\n scaffolderActions.addActions(\n createGetWorkflowParamsAction(discoveryService, authService),\n );\n },\n });\n },\n});\n"],"names":["createBackendModule","scaffolderActionsExtensionPoint","coreServices","createRunWorkflowAction","createGetWorkflowParamsAction"],"mappings":";;;;;;;AA6BO,MAAM,mBAAmBA,oCAAoB,CAAA;AAAA,EAClD,QAAU,EAAA,cAAA;AAAA,EACV,QAAU,EAAA,YAAA;AAAA,EACV,QAAA,CAAS,EAAE,YAAA,EAAgB,EAAA;AACzB,IAAa,YAAA,CAAA;AAAA,MACX,IAAM,EAAA;AAAA,QACJ,iBAAmB,EAAAC,qCAAA;AAAA,QACnB,kBAAkBC,6BAAa,CAAA,SAAA;AAAA,QAC/B,aAAaA,6BAAa,CAAA;AAAA,OAC5B;AAAA,MACA,MAAM,IAAK,CAAA,EAAE,iBAAmB,EAAA,gBAAA,EAAkB,aAAe,EAAA;AAC/D,QAAkB,iBAAA,CAAA,UAAA;AAAA,UAChBC,mCAAA,CAAwB,kBAAkB,WAAW;AAAA,SACvD;AACA,QAAkB,iBAAA,CAAA,UAAA;AAAA,UAChBC,+CAAA,CAA8B,kBAAkB,WAAW;AAAA,SAC7D;AAAA;AACF,KACD,CAAA;AAAA;AAEL,CAAC;;;;"}
package/package.json ADDED
@@ -0,0 +1,95 @@
1
+ {
2
+ "name": "@red-hat-developer-hub/backstage-plugin-scaffolder-backend-module-orchestrator",
3
+ "description": "The orchestrator module for @backstage/plugin-scaffolder-backend",
4
+ "version": "0.2.0",
5
+ "main": "./dist/index.cjs.js",
6
+ "types": "./dist/index.d.ts",
7
+ "license": "Apache-2.0",
8
+ "publishConfig": {
9
+ "access": "public"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://github.com/redhat-developer/rhdh-plugins",
14
+ "directory": "workspaces/orchestrator/plugins/scaffolder-backend-module-orchestrator"
15
+ },
16
+ "backstage": {
17
+ "role": "backend-plugin-module",
18
+ "pluginId": "scaffolder",
19
+ "supported-versions": "1.32.5",
20
+ "pluginPackages": [
21
+ "@red-hat-developer-hub/backstage-plugin-orchestrator-common",
22
+ "@red-hat-developer-hub/backstage-plugin-scaffolder-backend-module-orchestrator"
23
+ ],
24
+ "pluginPackage": "@backstage/plugin-scaffolder-backend",
25
+ "features": {
26
+ ".": "@backstage/BackendFeature"
27
+ }
28
+ },
29
+ "bugs": "https://github.com/redhat-developer/rhdh-plugins/issues",
30
+ "keywords": [
31
+ "support:tech-preview",
32
+ "lifecycle:active",
33
+ "backstage",
34
+ "plugin",
35
+ "orchestrator",
36
+ "workflows"
37
+ ],
38
+ "exports": {
39
+ ".": {
40
+ "backstage": "@backstage/BackendFeature",
41
+ "require": "./dist/index.cjs.js",
42
+ "types": "./dist/index.d.ts",
43
+ "default": "./dist/index.cjs.js"
44
+ },
45
+ "./package.json": "./package.json"
46
+ },
47
+ "typesVersions": {
48
+ "*": {
49
+ "index": [
50
+ "dist/index.d.ts"
51
+ ]
52
+ }
53
+ },
54
+ "scripts": {
55
+ "start": "backstage-cli package start",
56
+ "build": "backstage-cli package build",
57
+ "test": "backstage-cli package test",
58
+ "clean": "backstage-cli package clean",
59
+ "prepack": "backstage-cli package prepack",
60
+ "postpack": "backstage-cli package postpack",
61
+ "tsc": "tsc",
62
+ "prettier:check": "prettier --ignore-unknown --check .",
63
+ "prettier:fix": "prettier --ignore-unknown --write .",
64
+ "lint:check": "backstage-cli package lint",
65
+ "lint:fix": "backstage-cli package lint --fix",
66
+ "export-dynamic": "janus-cli package export-dynamic-plugin --no-embed-as-dependencies --embed-package '@red-hat-developer-hub/backstage-plugin-orchestrator-common'"
67
+ },
68
+ "dependencies": {
69
+ "@backstage/backend-plugin-api": "^1.2.0-next.2",
70
+ "@backstage/catalog-model": "^1.7.3",
71
+ "@backstage/plugin-scaffolder-node": "^0.7.0-next.2",
72
+ "@backstage/types": "^1.2.1",
73
+ "@red-hat-developer-hub/backstage-plugin-orchestrator-common": "^1.26.0",
74
+ "axios": "^1.7.9",
75
+ "js-yaml": "^4.1.0"
76
+ },
77
+ "devDependencies": {
78
+ "@backstage/cli": "^0.30.0-next.3",
79
+ "@backstage/plugin-scaffolder-node-test-utils": "^0.1.19-next.3",
80
+ "@janus-idp/cli": "3.2.0",
81
+ "@spotify/prettier-config": "^15.0.0"
82
+ },
83
+ "files": [
84
+ "app-config.yaml",
85
+ "dist",
86
+ "dist-dynamic/*.*",
87
+ "dist-dynamic/dist/**",
88
+ "static"
89
+ ],
90
+ "maintainers": [
91
+ "@mlibra",
92
+ "@batzionb",
93
+ "@gciavarrini"
94
+ ]
95
+ }