@red-hat-developer-hub/backstage-plugin-bulk-import-backend 6.10.1 → 6.11.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/README.md +115 -1
- package/config.d.ts +6 -1
- package/dist/database/repositoryDao.cjs.js +40 -9
- package/dist/database/repositoryDao.cjs.js.map +1 -1
- package/dist/generated/openapidocument.cjs.js +247 -1
- package/dist/generated/openapidocument.cjs.js.map +1 -1
- package/dist/github/githubApiService.cjs.js +14 -0
- package/dist/github/githubApiService.cjs.js.map +1 -1
- package/dist/gitlab/gitlabApiService.cjs.js +14 -0
- package/dist/gitlab/gitlabApiService.cjs.js.map +1 -1
- package/dist/service/handlers/import/bulkImports.cjs.js +139 -63
- package/dist/service/handlers/import/bulkImports.cjs.js.map +1 -1
- package/dist/service/handlers/import/execute-orchestrator-workflow.cjs.js +104 -0
- package/dist/service/handlers/import/execute-orchestrator-workflow.cjs.js.map +1 -0
- package/dist/service/handlers/import/execute-template.cjs.js +3 -7
- package/dist/service/handlers/import/execute-template.cjs.js.map +1 -1
- package/dist/service/handlers/repository/repositories.cjs.js +1 -0
- package/dist/service/handlers/repository/repositories.cjs.js.map +1 -1
- package/dist/service/router.cjs.js +129 -10
- package/dist/service/router.cjs.js.map +1 -1
- package/migrations/20251107150603_migrations.js +58 -0
- package/package.json +5 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
### Dependencies
|
|
2
2
|
|
|
3
|
+
## 6.11.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 9c17c36: Updated dependency `prettier` to `3.8.0`.
|
|
8
|
+
- Updated dependencies [9c17c36]
|
|
9
|
+
- @red-hat-developer-hub/backstage-plugin-bulk-import-common@6.11.1
|
|
10
|
+
|
|
11
|
+
## 6.11.0
|
|
12
|
+
|
|
13
|
+
### Minor Changes
|
|
14
|
+
|
|
15
|
+
- 88ac11d: Implement the execution of import orchestrator workflows with the help of the bulk-import plugin.
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- Updated dependencies [88ac11d]
|
|
20
|
+
- @red-hat-developer-hub/backstage-plugin-bulk-import-common@6.11.0
|
|
21
|
+
|
|
3
22
|
## 6.10.1
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -103,10 +103,11 @@ bulkImport:
|
|
|
103
103
|
importAPI: 'scaffolder'
|
|
104
104
|
```
|
|
105
105
|
|
|
106
|
-
importAPI: This field defines the import workflow. It currently supports
|
|
106
|
+
importAPI: This field defines the import workflow. It currently supports three options:
|
|
107
107
|
|
|
108
108
|
- open-pull-requests: This is the default import workflow, which includes the logic for creating pull requests for every selected repository.
|
|
109
109
|
- scaffolder: This workflow uses an import scenario defined in the scaffolder template. The import steps depend on the template's content, allowing for various scenarios. These can include importing existing catalog entities from a repository, creating pull requests, calling webhooks, and more. This method offers greater flexibility.
|
|
110
|
+
- orchestrator: This workflow uses the Orchestrator plugin to execute workflows for bulk import operations. This mode provides advanced workflow orchestration capabilities and integrates with the Backstage Orchestrator plugin.
|
|
110
111
|
|
|
111
112
|
> Important Note
|
|
112
113
|
> The scaffolder template must be generic and not specific to a single repository to be successfully executed for every repository in the bulk list.
|
|
@@ -176,6 +177,119 @@ parameters:
|
|
|
176
177
|
title: Git provider host
|
|
177
178
|
```
|
|
178
179
|
|
|
180
|
+
#### Orchestrator Workflow Execution
|
|
181
|
+
|
|
182
|
+
The Bulk Import plugin supports using the Orchestrator plugin to execute workflows for bulk import operations. This mode leverages the Orchestrator's workflow engine to provide advanced orchestration capabilities for importing repositories.
|
|
183
|
+
|
|
184
|
+
##### Plugin Configuration
|
|
185
|
+
|
|
186
|
+
To use the orchestrator mode, configure the Bulk Import plugin as follows:
|
|
187
|
+
|
|
188
|
+
```yaml
|
|
189
|
+
bulkImport:
|
|
190
|
+
orchestratorWorkflow: your-workflow-id
|
|
191
|
+
importAPI: 'orchestrator'
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**Configuration Parameters:**
|
|
195
|
+
|
|
196
|
+
- **`orchestratorWorkflow`** (required): The ID of the orchestrator workflow to execute for each repository. This workflow must be registered in the Orchestrator plugin.
|
|
197
|
+
- **`importAPI`**: Set to `'orchestrator'` to enable orchestrator workflow execution mode.
|
|
198
|
+
|
|
199
|
+
> **Important Notes:**
|
|
200
|
+
>
|
|
201
|
+
> - The Orchestrator plugin must be installed and configured in your Backstage instance.
|
|
202
|
+
> - The specified workflow must be available in the Orchestrator plugin.
|
|
203
|
+
> - The workflow must be generic and able to handle different repositories, as it will be executed for each repository in the bulk import list.
|
|
204
|
+
|
|
205
|
+
##### Orchestrator Workflow Input Parameters
|
|
206
|
+
|
|
207
|
+
When executing an orchestrator workflow, the Bulk Import plugin provides the following input data to the workflow:
|
|
208
|
+
|
|
209
|
+
- **`owner`** – Repository owner (organization or user name).
|
|
210
|
+
**Example:** For `https://github.com/redhat-developer/rhdh-plugins`, `owner` will be `redhat-developer`.
|
|
211
|
+
|
|
212
|
+
- **`repo`** – Repository name.
|
|
213
|
+
**Example:** For `https://github.com/redhat-developer/rhdh-plugins`, `repo` will be `rhdh-plugins`.
|
|
214
|
+
|
|
215
|
+
- **`baseBranch`** – Default branch of the Git repository (e.g., `main`, `master`).
|
|
216
|
+
|
|
217
|
+
- **`targetBranch`** – Target branch for the import operation. By default, this is set to `bulk-import-orchestrator`.
|
|
218
|
+
|
|
219
|
+
Additionally, the plugin automatically provides authentication tokens for the Git provider:
|
|
220
|
+
|
|
221
|
+
- **`authTokens`** – Array of authentication tokens for the Git provider:
|
|
222
|
+
- For GitHub repositories (`approvalTool: 'GIT'`): `{ token: <github-token>, provider: 'github' }`
|
|
223
|
+
- For GitLab repositories (`approvalTool: 'GITLAB'`): `{ token: <gitlab-token>, provider: 'gitlab' }`
|
|
224
|
+
|
|
225
|
+
The tokens are obtained from the configured GitHub/GitLab integrations in your Backstage instance.
|
|
226
|
+
|
|
227
|
+
##### How Orchestrator Mode Works
|
|
228
|
+
|
|
229
|
+
1. **Workflow Execution**: When you submit a bulk import request with `importAPI: 'orchestrator'`, the plugin:
|
|
230
|
+
- Iterates through each repository in the request
|
|
231
|
+
- Retrieves the appropriate Git provider credentials (GitHub or GitLab)
|
|
232
|
+
- Executes the specified orchestrator workflow for each repository
|
|
233
|
+
- Passes the repository information and authentication tokens as input data
|
|
234
|
+
|
|
235
|
+
2. **Workflow Tracking**: The plugin:
|
|
236
|
+
- Stores workflow instance IDs in the database
|
|
237
|
+
- Associates each workflow instance with its repository
|
|
238
|
+
- Tracks workflow execution status by querying the Orchestrator API
|
|
239
|
+
|
|
240
|
+
3. **Status Monitoring**: You can check the status of orchestrator workflows:
|
|
241
|
+
- The workflow status is mapped from Orchestrator states to Bulk Import statuses (e.g., `WORKFLOW_ACTIVE`, `WORKFLOW_COMPLETED`, `WORKFLOW_ERROR`)
|
|
242
|
+
- Status information includes the workflow instance ID, which can be used to view detailed workflow execution in the Orchestrator UI
|
|
243
|
+
|
|
244
|
+
##### API Endpoints for Orchestrator Mode
|
|
245
|
+
|
|
246
|
+
When using `importAPI: 'orchestrator'`, the following API endpoints are used:
|
|
247
|
+
|
|
248
|
+
- **`POST /api/bulk-import/orchestrator-workflows`** – Create orchestrator workflow import jobs
|
|
249
|
+
- **`GET /api/bulk-import/orchestrator-workflows`** – List all orchestrator workflow import jobs
|
|
250
|
+
- **`GET /api/bulk-import/orchestrator-import/by-repo`** – Get orchestrator workflow import status for a specific repository
|
|
251
|
+
- **`DELETE /api/bulk-import/orchestrator-import/by-repo`** – Delete orchestrator workflow records for a specific repository
|
|
252
|
+
|
|
253
|
+
##### Example Orchestrator Workflow
|
|
254
|
+
|
|
255
|
+
Your orchestrator workflow should accept the input parameters described above. Here's an example of how the workflow input data structure looks:
|
|
256
|
+
|
|
257
|
+
```json
|
|
258
|
+
{
|
|
259
|
+
"inputData": {
|
|
260
|
+
"owner": "redhat-developer",
|
|
261
|
+
"repo": "rhdh-plugins",
|
|
262
|
+
"baseBranch": "main",
|
|
263
|
+
"targetBranch": "bulk-import-orchestrator"
|
|
264
|
+
},
|
|
265
|
+
"authTokens": [
|
|
266
|
+
{
|
|
267
|
+
"token": "<github-token>",
|
|
268
|
+
"provider": "github"
|
|
269
|
+
}
|
|
270
|
+
]
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
The workflow can then use these parameters to perform operations such as:
|
|
275
|
+
|
|
276
|
+
- Creating catalog entities
|
|
277
|
+
- Generating pull requests
|
|
278
|
+
- Calling external APIs
|
|
279
|
+
- Performing custom import logic
|
|
280
|
+
|
|
281
|
+
##### Workflow Status Mapping
|
|
282
|
+
|
|
283
|
+
The plugin maps Orchestrator workflow states to Bulk Import status values:
|
|
284
|
+
|
|
285
|
+
- Orchestrator `ACTIVE` → `WORKFLOW_ACTIVE`
|
|
286
|
+
- Orchestrator `COMPLETED` → `WORKFLOW_COMPLETED`
|
|
287
|
+
- Orchestrator `ERROR` → `WORKFLOW_ERROR`
|
|
288
|
+
- Orchestrator `ABORTED` → `WORKFLOW_ABORTED`
|
|
289
|
+
- Other states are prefixed with `WORKFLOW_` and uppercased
|
|
290
|
+
|
|
291
|
+
If workflow status cannot be retrieved, the status is set to `WORKFLOW_FETCH_FAILED`.
|
|
292
|
+
|
|
179
293
|
### Audit Logging
|
|
180
294
|
|
|
181
295
|
Audit logging is backed by the [`@backstage/backend-plugin-api`](https://www.npmjs.com/package/@backstage/backend-plugin-api) package.
|
package/config.d.ts
CHANGED
|
@@ -17,9 +17,14 @@
|
|
|
17
17
|
export interface Config {
|
|
18
18
|
bulkImport?: {
|
|
19
19
|
/**
|
|
20
|
-
* The name of the scaffolder template to execute for importing a repository.
|
|
20
|
+
* The name of the scaffolder template or entity reference to execute for importing a repository.
|
|
21
21
|
* @visibility backend
|
|
22
22
|
*/
|
|
23
23
|
importTemplate?: string;
|
|
24
|
+
/**
|
|
25
|
+
* The orchestrator workflow id to execute for importing a repository.
|
|
26
|
+
* @visibility backend
|
|
27
|
+
*/
|
|
28
|
+
orchestratorWorkflow?: string;
|
|
24
29
|
};
|
|
25
30
|
}
|
|
@@ -25,41 +25,42 @@ async function paginateQuery(queryBuilder, page = 1, size = 10, search) {
|
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
27
|
class RepositoryDao {
|
|
28
|
-
constructor(knex, logger) {
|
|
28
|
+
constructor(knex, logger, tableName) {
|
|
29
29
|
this.knex = knex;
|
|
30
30
|
this.logger = logger;
|
|
31
|
+
this.tableName = tableName;
|
|
31
32
|
}
|
|
32
33
|
async findRepositories(page = 1, size = 10, search) {
|
|
33
34
|
this.logger.debug(
|
|
34
35
|
`Fetching repositories page=${page}, size=${size}, search=${search}`
|
|
35
36
|
);
|
|
36
|
-
const query = this.knex(
|
|
37
|
+
const query = this.knex(this.tableName).select("id", "url", "approvalTool");
|
|
37
38
|
const searchParam = { column: "url", term: search };
|
|
38
39
|
return paginateQuery(query, page, size, searchParam);
|
|
39
40
|
}
|
|
40
|
-
async insertRepository(repoUrl,
|
|
41
|
+
async insertRepository(repoUrl, taskOrWorkflowId, approvalTool) {
|
|
41
42
|
this.logger.debug(
|
|
42
|
-
`Saving
|
|
43
|
+
`Saving repository ${repoUrl} for task/workflow ${taskOrWorkflowId} to database..`
|
|
43
44
|
);
|
|
44
|
-
const repository = await this.knex(
|
|
45
|
+
const repository = await this.knex(this.tableName).where({ url: repoUrl }).first();
|
|
45
46
|
let repositoryId;
|
|
46
47
|
if (repository) {
|
|
47
48
|
repositoryId = repository.id;
|
|
48
49
|
} else {
|
|
49
|
-
const [newRepository] = await this.knex(
|
|
50
|
+
const [newRepository] = await this.knex(this.tableName).insert({ url: repoUrl, approvalTool }).returning("id");
|
|
50
51
|
repositoryId = newRepository.id;
|
|
51
52
|
}
|
|
52
53
|
return repositoryId;
|
|
53
54
|
}
|
|
54
55
|
async findRepositoryByUrl(url) {
|
|
55
56
|
this.logger.debug(`Fetching repository from database by url ${url}...`);
|
|
56
|
-
return await this.knex(
|
|
57
|
+
return await this.knex(this.tableName).where({ url }).first();
|
|
57
58
|
}
|
|
58
59
|
async deleteRepository(url) {
|
|
59
60
|
this.logger.debug(`Deleting repository from database by url ${url}...`);
|
|
60
|
-
const repository = await this.knex(
|
|
61
|
+
const repository = await this.knex(this.tableName).where({ url }).first();
|
|
61
62
|
if (repository) {
|
|
62
|
-
await this.knex(
|
|
63
|
+
await this.knex(this.tableName).where({ id: repository.id }).del();
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
66
|
}
|
|
@@ -109,7 +110,37 @@ class TaskLocationsDao {
|
|
|
109
110
|
);
|
|
110
111
|
}
|
|
111
112
|
}
|
|
113
|
+
class OrchestratorWorkflowDao {
|
|
114
|
+
constructor(knex) {
|
|
115
|
+
this.knex = knex;
|
|
116
|
+
}
|
|
117
|
+
async insertWorkflow(instanceId, repositoryId) {
|
|
118
|
+
const [newWorkflow] = await this.knex("orchestrator_workflows").insert({
|
|
119
|
+
instance_id: instanceId,
|
|
120
|
+
repositoryId
|
|
121
|
+
}).returning("id");
|
|
122
|
+
return newWorkflow.id;
|
|
123
|
+
}
|
|
124
|
+
async lastExecutedWorkflowByRepoId(repositoryId) {
|
|
125
|
+
const result = await this.knex("orchestrator_workflows").select({
|
|
126
|
+
id: "id",
|
|
127
|
+
instanceId: "instance_id",
|
|
128
|
+
repositoryId: "repositoryId",
|
|
129
|
+
createdAt: "created_at"
|
|
130
|
+
}).where({ repositoryId }).orderBy("created_at", "desc").first();
|
|
131
|
+
return result;
|
|
132
|
+
}
|
|
133
|
+
async findWorkflowsByRepositoryId(repositoryId) {
|
|
134
|
+
return await this.knex("orchestrator_workflows").where({ repositoryId }).select({
|
|
135
|
+
id: "id",
|
|
136
|
+
instanceId: "instance_id",
|
|
137
|
+
repositoryId: "repositoryId",
|
|
138
|
+
createdAt: "created_at"
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
112
142
|
|
|
143
|
+
exports.OrchestratorWorkflowDao = OrchestratorWorkflowDao;
|
|
113
144
|
exports.RepositoryDao = RepositoryDao;
|
|
114
145
|
exports.ScaffolderTaskDao = ScaffolderTaskDao;
|
|
115
146
|
exports.TaskLocationsDao = TaskLocationsDao;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repositoryDao.cjs.js","sources":["../../src/database/repositoryDao.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 */\n\nimport type { LoggerService } from '@backstage/backend-plugin-api';\n\nimport { Knex } from 'knex';\n\nimport { Components } from '../generated/openapi';\n\nexport interface Repository {\n id: number;\n url: string;\n approvalTool: Components.Schemas.ApprovalTool;\n}\n\nexport interface ScaffolderTask {\n taskId: string;\n scaffolderOptions: any;\n repositoryId: number;\n executedAt?: Date;\n}\n\nexport interface PaginatedResult<T> {\n data: T[];\n page: number;\n size: number;\n total: number;\n totalPages: number;\n}\n\nexport async function paginateQuery<T>(\n queryBuilder: Knex.QueryBuilder<any, T[]>,\n page: number = 1,\n size: number = 10,\n search?: { column: string; term?: string },\n): Promise<PaginatedResult<T>> {\n const offset = (page - 1) * size;\n\n let baseQuery = queryBuilder.clone();\n\n if (search?.term) {\n if (queryBuilder.client.dialect === 'postgres') {\n baseQuery = baseQuery.whereILike(search.column, `%${search.term}%`);\n } else {\n baseQuery = baseQuery.whereLike(search.column, `%${search.term}%`);\n }\n }\n\n const countQuery = baseQuery\n .clone()\n .clearSelect()\n .clearOrder()\n .count<{ count: string }[]>('* as count');\n\n const [rows, [{ count }]] = await Promise.all([\n baseQuery.clone().limit(size).offset(offset),\n countQuery,\n ]);\n\n const total = Number(count);\n\n return {\n data: rows as T[],\n page,\n size,\n total,\n totalPages: Math.ceil(total / size),\n };\n}\n\n// @internal\nexport class RepositoryDao {\n constructor(\n private readonly knex: Knex<any, any[]>,\n private readonly logger: LoggerService,\n ) {}\n\n async findRepositories(\n page: number = 1,\n size: number = 10,\n search?: string,\n ): Promise<PaginatedResult<Repository>> {\n this.logger.debug(\n `Fetching repositories page=${page}, size=${size}, search=${search}`,\n );\n const query = this.knex('repositories').select('id', 'url', 'approvalTool');\n const searchParam = { column: 'url', term: search };\n return paginateQuery<Repository>(query, page, size, searchParam);\n }\n\n async insertRepository(\n repoUrl: string,\n taskId: string,\n approvalTool: string,\n ): Promise<number> {\n this.logger.debug(\n `Saving task ${taskId} for repo ${repoUrl} to database..`,\n );\n const repository = await this.knex('repositories')\n .where({ url: repoUrl })\n .first();\n\n let repositoryId;\n if (repository) {\n repositoryId = repository.id;\n } else {\n const [newRepository] = await this.knex('repositories')\n .insert({ url: repoUrl, approvalTool: approvalTool })\n .returning('id');\n repositoryId = newRepository.id;\n }\n return repositoryId;\n }\n\n async findRepositoryByUrl(url: string): Promise<Repository | undefined> {\n this.logger.debug(`Fetching repository from database by url ${url}...`);\n return await this.knex('repositories').where({ url: url }).first();\n }\n\n async deleteRepository(url: string): Promise<void> {\n this.logger.debug(`Deleting repository from database by url ${url}...`);\n const repository = await this.knex('repositories')\n .where({ url: url })\n .first();\n\n if (repository) {\n await this.knex('repositories').where({ id: repository.id }).del();\n }\n }\n}\n\n// @internal\nexport class ScaffolderTaskDao {\n constructor(private readonly knex: Knex<any, any[]>) {}\n\n async findAllTasks(): Promise<ScaffolderTask[]> {\n return await this.knex('scaffolder_tasks').select<ScaffolderTask[]>(\n 'taskId',\n 'repositoryId',\n 'scaffolderOptions',\n );\n }\n\n async insertTask(task: ScaffolderTask): Promise<string> {\n const result = await this.knex('scaffolder_tasks')\n .insert<ScaffolderTask>({\n taskId: task.taskId,\n repositoryId: task.repositoryId,\n scaffolderOptions: JSON.stringify(task.scaffolderOptions),\n executedAt: task.executedAt,\n })\n .returning<{ taskId: string }[]>('taskId');\n\n return result[0].taskId;\n }\n\n async findTasksByRepositoryId(\n repositoryId: number,\n ): Promise<ScaffolderTask[]> {\n return await this.knex('scaffolder_tasks')\n .where({ repositoryId })\n .select<\n ScaffolderTask[]\n >('taskId', 'repositoryId', 'scaffolderOptions', 'executedAt');\n }\n\n async lastExecutedTaskByRepoId(\n repositoryId: number,\n ): Promise<ScaffolderTask | undefined> {\n return await this.knex('scaffolder_tasks')\n .where({ repositoryId })\n .orderBy('executedAt', 'desc')\n .first<ScaffolderTask>();\n }\n}\n\nexport interface TaskLocation {\n id: number;\n taskId: string;\n location: string;\n type: string;\n}\n\n// @internal\nexport class TaskLocationsDao {\n constructor(private readonly knex: Knex<any, any[]>) {}\n\n async addTaskLocation(\n taskId: string,\n location: string,\n type: string = 'component',\n ): Promise<void> {\n await this.knex('task_locations').insert({ taskId, location, type });\n }\n\n async findLocationsByTaskId(taskId: string): Promise<TaskLocation[]> {\n return await this.knex('task_locations')\n .where({ taskId })\n .select<TaskLocation[]>('id', 'taskId', 'location', 'type');\n }\n\n async findAllLocations(): Promise<TaskLocation[]> {\n return await this.knex('task_locations').select<TaskLocation[]>(\n 'id',\n 'taskId',\n 'location',\n 'type',\n );\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"repositoryDao.cjs.js","sources":["../../src/database/repositoryDao.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 */\n\nimport type { LoggerService } from '@backstage/backend-plugin-api';\n\nimport { Knex } from 'knex';\n\nimport { Components } from '../generated/openapi';\n\nexport interface Repository {\n id: number;\n url: string;\n approvalTool: Components.Schemas.ApprovalTool;\n}\n\nexport interface ScaffolderTask {\n taskId: string;\n scaffolderOptions: any;\n repositoryId: number;\n executedAt?: Date;\n}\n\nexport interface PaginatedResult<T> {\n data: T[];\n page: number;\n size: number;\n total: number;\n totalPages: number;\n}\n\nexport async function paginateQuery<T>(\n queryBuilder: Knex.QueryBuilder<any, T[]>,\n page: number = 1,\n size: number = 10,\n search?: { column: string; term?: string },\n): Promise<PaginatedResult<T>> {\n const offset = (page - 1) * size;\n\n let baseQuery = queryBuilder.clone();\n\n if (search?.term) {\n if (queryBuilder.client.dialect === 'postgres') {\n baseQuery = baseQuery.whereILike(search.column, `%${search.term}%`);\n } else {\n baseQuery = baseQuery.whereLike(search.column, `%${search.term}%`);\n }\n }\n\n const countQuery = baseQuery\n .clone()\n .clearSelect()\n .clearOrder()\n .count<{ count: string }[]>('* as count');\n\n const [rows, [{ count }]] = await Promise.all([\n baseQuery.clone().limit(size).offset(offset),\n countQuery,\n ]);\n\n const total = Number(count);\n\n return {\n data: rows as T[],\n page,\n size,\n total,\n totalPages: Math.ceil(total / size),\n };\n}\n\nexport type RepositoryName = 'repositories' | 'orchestrator_repositories';\n\n// @internal\nexport class RepositoryDao<R extends RepositoryName> {\n constructor(\n private readonly knex: Knex<any, any[]>,\n private readonly logger: LoggerService,\n private readonly tableName: R,\n ) {}\n\n async findRepositories(\n page: number = 1,\n size: number = 10,\n search?: string,\n ): Promise<PaginatedResult<Repository>> {\n this.logger.debug(\n `Fetching repositories page=${page}, size=${size}, search=${search}`,\n );\n const query = this.knex(this.tableName).select('id', 'url', 'approvalTool');\n const searchParam = { column: 'url', term: search };\n return paginateQuery<Repository>(query, page, size, searchParam);\n }\n\n async insertRepository(\n repoUrl: string,\n taskOrWorkflowId: string,\n approvalTool: string,\n ): Promise<number> {\n this.logger.debug(\n `Saving repository ${repoUrl} for task/workflow ${taskOrWorkflowId} to database..`,\n );\n const repository = await this.knex(this.tableName)\n .where({ url: repoUrl })\n .first();\n\n let repositoryId;\n if (repository) {\n repositoryId = repository.id;\n } else {\n const [newRepository] = await this.knex(this.tableName)\n .insert({ url: repoUrl, approvalTool: approvalTool })\n .returning('id');\n repositoryId = newRepository.id;\n }\n return repositoryId;\n }\n\n async findRepositoryByUrl(url: string): Promise<Repository | undefined> {\n this.logger.debug(`Fetching repository from database by url ${url}...`);\n return await this.knex(this.tableName).where({ url: url }).first();\n }\n\n async deleteRepository(url: string): Promise<void> {\n this.logger.debug(`Deleting repository from database by url ${url}...`);\n const repository = await this.knex(this.tableName)\n .where({ url: url })\n .first();\n\n if (repository) {\n await this.knex(this.tableName).where({ id: repository.id }).del();\n }\n }\n}\n\n// @internal\nexport class ScaffolderTaskDao {\n constructor(private readonly knex: Knex<any, any[]>) {}\n\n async findAllTasks(): Promise<ScaffolderTask[]> {\n return await this.knex('scaffolder_tasks').select<ScaffolderTask[]>(\n 'taskId',\n 'repositoryId',\n 'scaffolderOptions',\n );\n }\n\n async insertTask(task: ScaffolderTask): Promise<string> {\n const result = await this.knex('scaffolder_tasks')\n .insert<ScaffolderTask>({\n taskId: task.taskId,\n repositoryId: task.repositoryId,\n scaffolderOptions: JSON.stringify(task.scaffolderOptions),\n executedAt: task.executedAt,\n })\n .returning<{ taskId: string }[]>('taskId');\n\n return result[0].taskId;\n }\n\n async findTasksByRepositoryId(\n repositoryId: number,\n ): Promise<ScaffolderTask[]> {\n return await this.knex('scaffolder_tasks')\n .where({ repositoryId })\n .select<\n ScaffolderTask[]\n >('taskId', 'repositoryId', 'scaffolderOptions', 'executedAt');\n }\n\n async lastExecutedTaskByRepoId(\n repositoryId: number,\n ): Promise<ScaffolderTask | undefined> {\n return await this.knex('scaffolder_tasks')\n .where({ repositoryId })\n .orderBy('executedAt', 'desc')\n .first<ScaffolderTask>();\n }\n}\n\nexport interface TaskLocation {\n id: number;\n taskId: string;\n location: string;\n type: string;\n}\n\n// @internal\nexport class TaskLocationsDao {\n constructor(private readonly knex: Knex<any, any[]>) {}\n\n async addTaskLocation(\n taskId: string,\n location: string,\n type: string = 'component',\n ): Promise<void> {\n await this.knex('task_locations').insert({ taskId, location, type });\n }\n\n async findLocationsByTaskId(taskId: string): Promise<TaskLocation[]> {\n return await this.knex('task_locations')\n .where({ taskId })\n .select<TaskLocation[]>('id', 'taskId', 'location', 'type');\n }\n\n async findAllLocations(): Promise<TaskLocation[]> {\n return await this.knex('task_locations').select<TaskLocation[]>(\n 'id',\n 'taskId',\n 'location',\n 'type',\n );\n }\n}\n\nexport interface OrchestratorWorkflow {\n id: number;\n instanceId: string;\n repositoryId: number;\n createdAt: Date;\n status?: string;\n}\n\n// @internal\nexport class OrchestratorWorkflowDao {\n constructor(private readonly knex: Knex<any, any[]>) {}\n\n async insertWorkflow(\n instanceId: string,\n repositoryId: number,\n ): Promise<number> {\n const [newWorkflow] = await this.knex('orchestrator_workflows')\n .insert({\n instance_id: instanceId,\n repositoryId: repositoryId,\n })\n .returning('id');\n return newWorkflow.id;\n }\n\n async lastExecutedWorkflowByRepoId(\n repositoryId: number,\n ): Promise<OrchestratorWorkflow | undefined> {\n const result = await this.knex('orchestrator_workflows')\n .select({\n id: 'id',\n instanceId: 'instance_id',\n repositoryId: 'repositoryId',\n createdAt: 'created_at',\n })\n .where({ repositoryId: repositoryId })\n .orderBy('created_at', 'desc')\n .first();\n return result;\n }\n\n async findWorkflowsByRepositoryId(\n repositoryId: number,\n ): Promise<OrchestratorWorkflow[]> {\n return await this.knex('orchestrator_workflows')\n .where({ repositoryId: repositoryId })\n .select({\n id: 'id',\n instanceId: 'instance_id',\n repositoryId: 'repositoryId',\n createdAt: 'created_at',\n });\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -562,6 +562,135 @@ const OPENAPI = `
|
|
|
562
562
|
}
|
|
563
563
|
}
|
|
564
564
|
},
|
|
565
|
+
"/orchestrator-workflows": {
|
|
566
|
+
"get": {
|
|
567
|
+
"operationId": "findAllOrchestratorWorkflowImports",
|
|
568
|
+
"summary": "Fetch Import Jobs",
|
|
569
|
+
"security": [
|
|
570
|
+
{
|
|
571
|
+
"BearerAuth": []
|
|
572
|
+
}
|
|
573
|
+
],
|
|
574
|
+
"tags": [
|
|
575
|
+
"Import"
|
|
576
|
+
],
|
|
577
|
+
"parameters": [
|
|
578
|
+
{
|
|
579
|
+
"$ref": "#/components/parameters/apiVersionHeaderParam"
|
|
580
|
+
},
|
|
581
|
+
{
|
|
582
|
+
"$ref": "#/components/parameters/pagePerIntegrationQueryParamDeprecated"
|
|
583
|
+
},
|
|
584
|
+
{
|
|
585
|
+
"$ref": "#/components/parameters/sizePerIntegrationQueryParamDeprecated"
|
|
586
|
+
},
|
|
587
|
+
{
|
|
588
|
+
"$ref": "#/components/parameters/pageQueryParam"
|
|
589
|
+
},
|
|
590
|
+
{
|
|
591
|
+
"$ref": "#/components/parameters/sizeQueryParam"
|
|
592
|
+
},
|
|
593
|
+
{
|
|
594
|
+
"$ref": "#/components/parameters/sortOrderQueryParam"
|
|
595
|
+
},
|
|
596
|
+
{
|
|
597
|
+
"$ref": "#/components/parameters/sortColumnQueryParam"
|
|
598
|
+
},
|
|
599
|
+
{
|
|
600
|
+
"$ref": "#/components/parameters/searchQueryParam"
|
|
601
|
+
}
|
|
602
|
+
],
|
|
603
|
+
"responses": {
|
|
604
|
+
"200": {
|
|
605
|
+
"description": "Import Job list was fetched successfully with no errors",
|
|
606
|
+
"content": {
|
|
607
|
+
"application/json": {
|
|
608
|
+
"schema": {
|
|
609
|
+
"oneOf": [
|
|
610
|
+
{
|
|
611
|
+
"type": "array",
|
|
612
|
+
"items": {
|
|
613
|
+
"$ref": "#/components/schemas/SourceImport"
|
|
614
|
+
}
|
|
615
|
+
},
|
|
616
|
+
{
|
|
617
|
+
"$ref": "#/components/schemas/ImportJobListV2"
|
|
618
|
+
}
|
|
619
|
+
]
|
|
620
|
+
},
|
|
621
|
+
"examples": {
|
|
622
|
+
"twoImports": {
|
|
623
|
+
"$ref": "#/components/examples/twoImports"
|
|
624
|
+
},
|
|
625
|
+
"multipleImportJobsV2": {
|
|
626
|
+
"$ref": "#/components/examples/multipleImportJobsV2"
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
},
|
|
632
|
+
"500": {
|
|
633
|
+
"description": "Generic error when there are errors and no Import Job is returned",
|
|
634
|
+
"content": {
|
|
635
|
+
"application/json": {
|
|
636
|
+
"schema": {
|
|
637
|
+
"oneOf": [
|
|
638
|
+
{
|
|
639
|
+
"type": "string",
|
|
640
|
+
"description": "Generic error"
|
|
641
|
+
},
|
|
642
|
+
{
|
|
643
|
+
"$ref": "#/components/schemas/ImportJobListV2"
|
|
644
|
+
}
|
|
645
|
+
]
|
|
646
|
+
},
|
|
647
|
+
"examples": {
|
|
648
|
+
"repositoryListErrors": {
|
|
649
|
+
"$ref": "#/components/examples/importJobListErrors"
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
},
|
|
657
|
+
"post": {
|
|
658
|
+
"operationId": "createOrchestratorWorkflowJobs",
|
|
659
|
+
"summary": "Execute an orchestrator workflow",
|
|
660
|
+
"security": [
|
|
661
|
+
{
|
|
662
|
+
"BearerAuth": []
|
|
663
|
+
}
|
|
664
|
+
],
|
|
665
|
+
"tags": [
|
|
666
|
+
"Import"
|
|
667
|
+
],
|
|
668
|
+
"requestBody": {
|
|
669
|
+
"description": "List of Import jobs to create",
|
|
670
|
+
"required": true,
|
|
671
|
+
"content": {
|
|
672
|
+
"application/json": {
|
|
673
|
+
"schema": {
|
|
674
|
+
"type": "array",
|
|
675
|
+
"items": {
|
|
676
|
+
"$ref": "#/components/schemas/ImportRequest"
|
|
677
|
+
}
|
|
678
|
+
},
|
|
679
|
+
"examples": {
|
|
680
|
+
"multipleImportRequests": {
|
|
681
|
+
"$ref": "#/components/examples/multipleImportRequests"
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
},
|
|
687
|
+
"responses": {
|
|
688
|
+
"200": {
|
|
689
|
+
"description": "The orchestrator workflow was triggered successfully."
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
},
|
|
565
694
|
"/task-import/by-repo": {
|
|
566
695
|
"get": {
|
|
567
696
|
"operationId": "findTaskImportStatusByRepo",
|
|
@@ -651,6 +780,86 @@ const OPENAPI = `
|
|
|
651
780
|
}
|
|
652
781
|
}
|
|
653
782
|
},
|
|
783
|
+
"/orchestrator-import/by-repo": {
|
|
784
|
+
"get": {
|
|
785
|
+
"operationId": "findOrchestratorImportStatusByRepo",
|
|
786
|
+
"summary": "Get Import Status by repository",
|
|
787
|
+
"security": [
|
|
788
|
+
{
|
|
789
|
+
"BearerAuth": []
|
|
790
|
+
}
|
|
791
|
+
],
|
|
792
|
+
"tags": [
|
|
793
|
+
"Import"
|
|
794
|
+
],
|
|
795
|
+
"parameters": [
|
|
796
|
+
{
|
|
797
|
+
"in": "query",
|
|
798
|
+
"name": "repo",
|
|
799
|
+
"description": "the full URL to the repo",
|
|
800
|
+
"schema": {
|
|
801
|
+
"type": "string"
|
|
802
|
+
}
|
|
803
|
+
},
|
|
804
|
+
{
|
|
805
|
+
"$ref": "#/components/parameters/approvalToolParam"
|
|
806
|
+
}
|
|
807
|
+
],
|
|
808
|
+
"responses": {
|
|
809
|
+
"200": {
|
|
810
|
+
"description": "Import Job status was determined successfully with no errors",
|
|
811
|
+
"content": {
|
|
812
|
+
"application/json": {
|
|
813
|
+
"schema": {
|
|
814
|
+
"$ref": "#/components/schemas/Import"
|
|
815
|
+
},
|
|
816
|
+
"examples": {
|
|
817
|
+
"singleImportStatusForRepo": {
|
|
818
|
+
"$ref": "#/components/examples/singleImportStatusForRepo"
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
},
|
|
824
|
+
"500": {
|
|
825
|
+
"description": "Generic error"
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
},
|
|
829
|
+
"delete": {
|
|
830
|
+
"operationId": "deleteOrchestratorImportByRepo",
|
|
831
|
+
"summary": "Delete stored orchestrator workflow records for a specific repository",
|
|
832
|
+
"security": [
|
|
833
|
+
{
|
|
834
|
+
"BearerAuth": []
|
|
835
|
+
}
|
|
836
|
+
],
|
|
837
|
+
"tags": [
|
|
838
|
+
"Import"
|
|
839
|
+
],
|
|
840
|
+
"parameters": [
|
|
841
|
+
{
|
|
842
|
+
"in": "query",
|
|
843
|
+
"name": "repo",
|
|
844
|
+
"description": "the full URL to the repo",
|
|
845
|
+
"schema": {
|
|
846
|
+
"type": "string"
|
|
847
|
+
}
|
|
848
|
+
},
|
|
849
|
+
{
|
|
850
|
+
"$ref": "#/components/parameters/approvalToolParam"
|
|
851
|
+
}
|
|
852
|
+
],
|
|
853
|
+
"responses": {
|
|
854
|
+
"204": {
|
|
855
|
+
"description": "Repository was deleted successfully with no errors"
|
|
856
|
+
},
|
|
857
|
+
"500": {
|
|
858
|
+
"description": "Generic error"
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
},
|
|
654
863
|
"/import/by-repo": {
|
|
655
864
|
"get": {
|
|
656
865
|
"operationId": "findImportStatusByRepo",
|
|
@@ -983,6 +1192,9 @@ const OPENAPI = `
|
|
|
983
1192
|
},
|
|
984
1193
|
{
|
|
985
1194
|
"$ref": "#/components/schemas/TaskImportStatus"
|
|
1195
|
+
},
|
|
1196
|
+
{
|
|
1197
|
+
"$ref": "#/components/schemas/WorkflowImportStatus"
|
|
986
1198
|
}
|
|
987
1199
|
]
|
|
988
1200
|
},
|
|
@@ -1012,7 +1224,6 @@ const OPENAPI = `
|
|
|
1012
1224
|
},
|
|
1013
1225
|
"TaskImportStatus": {
|
|
1014
1226
|
"type": "string",
|
|
1015
|
-
"nullable": true,
|
|
1016
1227
|
"description": "Import Job status",
|
|
1017
1228
|
"enum": [
|
|
1018
1229
|
"TASK_CANCELLED",
|
|
@@ -1076,6 +1287,9 @@ const OPENAPI = `
|
|
|
1076
1287
|
},
|
|
1077
1288
|
{
|
|
1078
1289
|
"$ref": "#/components/schemas/TaskImportStatus"
|
|
1290
|
+
},
|
|
1291
|
+
{
|
|
1292
|
+
"$ref": "#/components/schemas/WorkflowImportStatus"
|
|
1079
1293
|
}
|
|
1080
1294
|
]
|
|
1081
1295
|
},
|
|
@@ -1087,6 +1301,14 @@ const OPENAPI = `
|
|
|
1087
1301
|
}
|
|
1088
1302
|
}
|
|
1089
1303
|
},
|
|
1304
|
+
"workflow": {
|
|
1305
|
+
"type": "object",
|
|
1306
|
+
"properties": {
|
|
1307
|
+
"workflowId": {
|
|
1308
|
+
"type": "string"
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
},
|
|
1090
1312
|
"tasks": {
|
|
1091
1313
|
"type": "array",
|
|
1092
1314
|
"items": {
|
|
@@ -1098,6 +1320,17 @@ const OPENAPI = `
|
|
|
1098
1320
|
}
|
|
1099
1321
|
}
|
|
1100
1322
|
},
|
|
1323
|
+
"workflows": {
|
|
1324
|
+
"type": "array",
|
|
1325
|
+
"items": {
|
|
1326
|
+
"type": "object",
|
|
1327
|
+
"properties": {
|
|
1328
|
+
"workflowId": {
|
|
1329
|
+
"type": "string"
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
},
|
|
1101
1334
|
"catalogEntityName": {
|
|
1102
1335
|
"type": "string",
|
|
1103
1336
|
"description": "Specified entity name in the catalog. Filled only in response for dry-run import requests."
|
|
@@ -1281,6 +1514,19 @@ const OPENAPI = `
|
|
|
1281
1514
|
}
|
|
1282
1515
|
}
|
|
1283
1516
|
}
|
|
1517
|
+
},
|
|
1518
|
+
"WorkflowImportStatus": {
|
|
1519
|
+
"type": "string",
|
|
1520
|
+
"description": "Import Job status",
|
|
1521
|
+
"enum": [
|
|
1522
|
+
"WORKFLOW_ACTIVE",
|
|
1523
|
+
"WORKFLOW_COMPLETED",
|
|
1524
|
+
"WORKFLOW_ABORTED",
|
|
1525
|
+
"WORKFLOW_SUSPENDED",
|
|
1526
|
+
"WORKFLOW_ERROR",
|
|
1527
|
+
"WORKFLOW_PENDING",
|
|
1528
|
+
"WORKFLOW_FETCH_FAILED"
|
|
1529
|
+
]
|
|
1284
1530
|
}
|
|
1285
1531
|
},
|
|
1286
1532
|
"securitySchemes": {
|