@backstage/plugin-catalog-backend 0.21.0-next.0 → 0.21.2-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +122 -0
- package/dist/index.cjs.js +65 -8
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +52 -6
- package/package.json +16 -16
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,127 @@
|
|
|
1
1
|
# @backstage/plugin-catalog-backend
|
|
2
2
|
|
|
3
|
+
## 0.21.2-next.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
- @backstage/plugin-catalog-common@0.1.2-next.0
|
|
9
|
+
- @backstage/backend-common@0.10.6-next.0
|
|
10
|
+
- @backstage/plugin-permission-node@0.4.2-next.1
|
|
11
|
+
|
|
12
|
+
## 0.21.2-next.0
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- fac5f112b4: chore(deps): bump `prom-client` from 13.2.0 to 14.0.1
|
|
17
|
+
- 5bbffa60be: Pass authorization token to location service inside location api routes
|
|
18
|
+
- Updated dependencies
|
|
19
|
+
- @backstage/plugin-permission-node@0.4.2-next.0
|
|
20
|
+
|
|
21
|
+
## 0.21.1
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- 4f5bde47e9: Add support for permissions to the DefaultCatalogCollator.
|
|
26
|
+
- Updated dependencies
|
|
27
|
+
- @backstage/search-common@0.2.2
|
|
28
|
+
- @backstage/backend-common@0.10.5
|
|
29
|
+
- @backstage/plugin-permission-node@0.4.1
|
|
30
|
+
|
|
31
|
+
## 0.21.0
|
|
32
|
+
|
|
33
|
+
### Minor Changes
|
|
34
|
+
|
|
35
|
+
- 9f2a8dc423: **BREAKING**: Removed all remnants of the old catalog engine implementation.
|
|
36
|
+
|
|
37
|
+
The old implementation has been deprecated for over half a year. To ensure that
|
|
38
|
+
you are not using the old implementation, check that your
|
|
39
|
+
`packages/backend/src/plugins/catalog.ts` creates the catalog builder using
|
|
40
|
+
`CatalogBuilder.create`. If you instead call `new CatalogBuilder`, you are on
|
|
41
|
+
the old implementation and will experience breakage if you upgrade to this
|
|
42
|
+
version. If you are still on the old version, see [the relevant change log
|
|
43
|
+
entry](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend/CHANGELOG.md#patch-changes-27)
|
|
44
|
+
for migration instructions.
|
|
45
|
+
|
|
46
|
+
The minimal `packages/backend/src/plugins/catalog.ts` file is now:
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
export default async function createPlugin(
|
|
50
|
+
env: PluginEnvironment,
|
|
51
|
+
): Promise<Router> {
|
|
52
|
+
const builder = await CatalogBuilder.create(env);
|
|
53
|
+
builder.addProcessor(new ScaffolderEntitiesProcessor());
|
|
54
|
+
const { processingEngine, router } = await builder.build();
|
|
55
|
+
await processingEngine.start();
|
|
56
|
+
return router;
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The following classes and interfaces have been removed:
|
|
61
|
+
|
|
62
|
+
- The `CatalogBuilder` constructor (see above; use `CatalogBuilder.create`
|
|
63
|
+
instead)
|
|
64
|
+
- `AddLocationResult`
|
|
65
|
+
- `CommonDatabase`
|
|
66
|
+
- `CreateDatabaseOptions`
|
|
67
|
+
- `createNextRouter` (use `createRouter` instead - or preferably, use the
|
|
68
|
+
`router` field returned for you by `catalogBuilder.build()`)
|
|
69
|
+
- `Database`
|
|
70
|
+
- `DatabaseEntitiesCatalog` (use `EntitiesCatalog` instead)
|
|
71
|
+
- `DatabaseLocationsCatalog` (use `LocationService` instead)
|
|
72
|
+
- `DatabaseLocationUpdateLogEvent`
|
|
73
|
+
- `DatabaseLocationUpdateLogStatus`
|
|
74
|
+
- `DatabaseManager`
|
|
75
|
+
- `DbEntitiesRequest`
|
|
76
|
+
- `DbEntitiesResponse`
|
|
77
|
+
- `DbEntityRequest`
|
|
78
|
+
- `DbEntityResponse`
|
|
79
|
+
- `DbLocationsRow`
|
|
80
|
+
- `DbLocationsRowWithStatus`
|
|
81
|
+
- `DbPageInfo`
|
|
82
|
+
- `EntitiesCatalog.batchAddOrUpdateEntities` (was only used by the legacy
|
|
83
|
+
engine)
|
|
84
|
+
- `EntityUpsertRequest`
|
|
85
|
+
- `EntityUpsertResponse`
|
|
86
|
+
- `HigherOrderOperation`
|
|
87
|
+
- `HigherOrderOperations`
|
|
88
|
+
- `LocationReader`
|
|
89
|
+
- `LocationReaders`
|
|
90
|
+
- `LocationResponse`
|
|
91
|
+
- `LocationsCatalog`
|
|
92
|
+
- `LocationUpdateLogEvent`
|
|
93
|
+
- `LocationUpdateStatus`
|
|
94
|
+
- `NextCatalogBuilder` (use `CatalogBuilder.create` instead)
|
|
95
|
+
- `NextRouterOptions` (use `RouterOptions` instead)
|
|
96
|
+
- `ReadLocationEntity`
|
|
97
|
+
- `ReadLocationError`
|
|
98
|
+
- `ReadLocationResult`
|
|
99
|
+
- `Transaction`
|
|
100
|
+
|
|
101
|
+
The `RouterOptions` interface has been un-deprecated, and has instead found use
|
|
102
|
+
for passing into `createRouter`. Its shape has been significantly changed to
|
|
103
|
+
accommodate the new router.
|
|
104
|
+
|
|
105
|
+
### Patch Changes
|
|
106
|
+
|
|
107
|
+
- e15ce5c16e: Integrate authorization into the delete entities endpoint
|
|
108
|
+
- dce98a92f7: Now when entities are deleted, the parent entity state is updated such that it will "heal" accidental deletes on the next refresh round.
|
|
109
|
+
- 02687954ca: Fixed a typo and made a little clarification to a warning message
|
|
110
|
+
- 48248e2db5: Integrate permissions into entity ancestry endpoint in catalog-backend
|
|
111
|
+
- 68edbbeafd: Fix bug with resource loading in permission integration
|
|
112
|
+
- 7e38acaa9e: Integrate permissions into catalog-backend location endpoints
|
|
113
|
+
- 6680853e0c: Export conditional permission policy helpers from catalog-backend
|
|
114
|
+
- 2b27e49eb1: Internal update to match status field changes in `@backstage/catalog-model`.
|
|
115
|
+
- Updated dependencies
|
|
116
|
+
- @backstage/integration@0.7.2
|
|
117
|
+
- @backstage/plugin-permission-common@0.4.0
|
|
118
|
+
- @backstage/backend-common@0.10.4
|
|
119
|
+
- @backstage/config@0.1.13
|
|
120
|
+
- @backstage/plugin-permission-node@0.4.0
|
|
121
|
+
- @backstage/plugin-catalog-common@0.1.1
|
|
122
|
+
- @backstage/catalog-model@0.9.10
|
|
123
|
+
- @backstage/catalog-client@0.5.5
|
|
124
|
+
|
|
3
125
|
## 0.21.0-next.0
|
|
4
126
|
|
|
5
127
|
### Minor Changes
|
package/dist/index.cjs.js
CHANGED
|
@@ -21,6 +21,7 @@ var graphql = require('@octokit/graphql');
|
|
|
21
21
|
var backendCommon = require('@backstage/backend-common');
|
|
22
22
|
var yaml = require('yaml');
|
|
23
23
|
var catalogClient = require('@backstage/catalog-client');
|
|
24
|
+
var pluginCatalogCommon = require('@backstage/plugin-catalog-common');
|
|
24
25
|
var crypto = require('crypto');
|
|
25
26
|
var express = require('express');
|
|
26
27
|
var Router = require('express-promise-router');
|
|
@@ -29,7 +30,6 @@ var uuid = require('uuid');
|
|
|
29
30
|
var luxon = require('luxon');
|
|
30
31
|
var promClient = require('prom-client');
|
|
31
32
|
var stableStringify = require('fast-json-stable-stringify');
|
|
32
|
-
var pluginCatalogCommon = require('@backstage/plugin-catalog-common');
|
|
33
33
|
var pluginPermissionCommon = require('@backstage/plugin-permission-common');
|
|
34
34
|
var pluginPermissionNode = require('@backstage/plugin-permission-node');
|
|
35
35
|
|
|
@@ -1930,6 +1930,7 @@ function withLocations(baseUrl, org, entity) {
|
|
|
1930
1930
|
class DefaultCatalogCollator {
|
|
1931
1931
|
constructor(options) {
|
|
1932
1932
|
this.type = "software-catalog";
|
|
1933
|
+
this.visibilityPermission = pluginCatalogCommon.catalogEntityReadPermission;
|
|
1933
1934
|
const { discovery, locationTemplate, filter, catalogClient: catalogClient$1, tokenManager } = options;
|
|
1934
1935
|
this.discovery = discovery;
|
|
1935
1936
|
this.locationTemplate = locationTemplate || "/catalog/:namespace/:kind/:name";
|
|
@@ -1984,7 +1985,10 @@ class DefaultCatalogCollator {
|
|
|
1984
1985
|
namespace: entity.metadata.namespace || "default",
|
|
1985
1986
|
kind: entity.kind,
|
|
1986
1987
|
lifecycle: ((_d = entity.spec) == null ? void 0 : _d.lifecycle) || "",
|
|
1987
|
-
owner: ((_e = entity.spec) == null ? void 0 : _e.owner) || ""
|
|
1988
|
+
owner: ((_e = entity.spec) == null ? void 0 : _e.owner) || "",
|
|
1989
|
+
authorization: {
|
|
1990
|
+
resourceRef: catalogModel.stringifyEntityRef(entity)
|
|
1991
|
+
}
|
|
1988
1992
|
};
|
|
1989
1993
|
});
|
|
1990
1994
|
}
|
|
@@ -2662,19 +2666,27 @@ async function createRouter(options) {
|
|
|
2662
2666
|
if (!dryRun) {
|
|
2663
2667
|
disallowReadonlyMode(readonlyEnabled);
|
|
2664
2668
|
}
|
|
2665
|
-
const output = await locationService.createLocation(input, dryRun
|
|
2669
|
+
const output = await locationService.createLocation(input, dryRun, {
|
|
2670
|
+
authorizationToken: getBearerToken(req.header("authorization"))
|
|
2671
|
+
});
|
|
2666
2672
|
res.status(201).json(output);
|
|
2667
|
-
}).get("/locations", async (
|
|
2668
|
-
const locations = await locationService.listLocations(
|
|
2673
|
+
}).get("/locations", async (req, res) => {
|
|
2674
|
+
const locations = await locationService.listLocations({
|
|
2675
|
+
authorizationToken: getBearerToken(req.header("authorization"))
|
|
2676
|
+
});
|
|
2669
2677
|
res.status(200).json(locations.map((l) => ({ data: l })));
|
|
2670
2678
|
}).get("/locations/:id", async (req, res) => {
|
|
2671
2679
|
const { id } = req.params;
|
|
2672
|
-
const output = await locationService.getLocation(id
|
|
2680
|
+
const output = await locationService.getLocation(id, {
|
|
2681
|
+
authorizationToken: getBearerToken(req.header("authorization"))
|
|
2682
|
+
});
|
|
2673
2683
|
res.status(200).json(output);
|
|
2674
2684
|
}).delete("/locations/:id", async (req, res) => {
|
|
2675
2685
|
disallowReadonlyMode(readonlyEnabled);
|
|
2676
2686
|
const { id } = req.params;
|
|
2677
|
-
await locationService.deleteLocation(id
|
|
2687
|
+
await locationService.deleteLocation(id, {
|
|
2688
|
+
authorizationToken: getBearerToken(req.header("authorization"))
|
|
2689
|
+
});
|
|
2678
2690
|
res.status(204).end();
|
|
2679
2691
|
});
|
|
2680
2692
|
}
|
|
@@ -4235,6 +4247,41 @@ class AuthorizedEntitiesCatalog {
|
|
|
4235
4247
|
}
|
|
4236
4248
|
}
|
|
4237
4249
|
|
|
4250
|
+
class AuthorizedLocationService {
|
|
4251
|
+
constructor(locationService, permissionApi) {
|
|
4252
|
+
this.locationService = locationService;
|
|
4253
|
+
this.permissionApi = permissionApi;
|
|
4254
|
+
}
|
|
4255
|
+
async createLocation(spec, dryRun, options) {
|
|
4256
|
+
const authorizationResponse = (await this.permissionApi.authorize([{ permission: pluginCatalogCommon.catalogLocationCreatePermission }], { token: options == null ? void 0 : options.authorizationToken }))[0];
|
|
4257
|
+
if (authorizationResponse.result === pluginPermissionCommon.AuthorizeResult.DENY) {
|
|
4258
|
+
throw new errors.NotAllowedError();
|
|
4259
|
+
}
|
|
4260
|
+
return this.locationService.createLocation(spec, dryRun);
|
|
4261
|
+
}
|
|
4262
|
+
async listLocations(options) {
|
|
4263
|
+
const authorizationResponse = (await this.permissionApi.authorize([{ permission: pluginCatalogCommon.catalogLocationReadPermission }], { token: options == null ? void 0 : options.authorizationToken }))[0];
|
|
4264
|
+
if (authorizationResponse.result === pluginPermissionCommon.AuthorizeResult.DENY) {
|
|
4265
|
+
return [];
|
|
4266
|
+
}
|
|
4267
|
+
return this.locationService.listLocations();
|
|
4268
|
+
}
|
|
4269
|
+
async getLocation(id, options) {
|
|
4270
|
+
const authorizationResponse = (await this.permissionApi.authorize([{ permission: pluginCatalogCommon.catalogLocationReadPermission }], { token: options == null ? void 0 : options.authorizationToken }))[0];
|
|
4271
|
+
if (authorizationResponse.result === pluginPermissionCommon.AuthorizeResult.DENY) {
|
|
4272
|
+
throw new errors.NotFoundError(`Found no location with ID ${id}`);
|
|
4273
|
+
}
|
|
4274
|
+
return this.locationService.getLocation(id);
|
|
4275
|
+
}
|
|
4276
|
+
async deleteLocation(id, options) {
|
|
4277
|
+
const authorizationResponse = (await this.permissionApi.authorize([{ permission: pluginCatalogCommon.catalogLocationDeletePermission }], { token: options == null ? void 0 : options.authorizationToken }))[0];
|
|
4278
|
+
if (authorizationResponse.result === pluginPermissionCommon.AuthorizeResult.DENY) {
|
|
4279
|
+
throw new errors.NotAllowedError();
|
|
4280
|
+
}
|
|
4281
|
+
return this.locationService.deleteLocation(id);
|
|
4282
|
+
}
|
|
4283
|
+
}
|
|
4284
|
+
|
|
4238
4285
|
class CatalogBuilder {
|
|
4239
4286
|
constructor(env) {
|
|
4240
4287
|
this.refreshInterval = createRandomRefreshInterval({
|
|
@@ -4384,7 +4431,7 @@ class CatalogBuilder {
|
|
|
4384
4431
|
const entityProviders = lodash__default["default"].uniqBy([...this.entityProviders, locationStore, configLocationProvider], (provider) => provider.getProviderName());
|
|
4385
4432
|
const processingEngine = new DefaultCatalogProcessingEngine(logger, processingDatabase, orchestrator, stitcher, () => crypto.createHash("sha1"));
|
|
4386
4433
|
const locationAnalyzer = (_b = this.locationAnalyzer) != null ? _b : new RepoLocationAnalyzer(logger, integrations);
|
|
4387
|
-
const locationService = new DefaultLocationService(locationStore, orchestrator);
|
|
4434
|
+
const locationService = new AuthorizedLocationService(new DefaultLocationService(locationStore, orchestrator), permissions);
|
|
4388
4435
|
const refreshService = new AuthorizedRefreshService(new DefaultRefreshService({ database: processingDatabase }), permissions);
|
|
4389
4436
|
const router = await createRouter({
|
|
4390
4437
|
entitiesCatalog,
|
|
@@ -4455,6 +4502,14 @@ class CatalogBuilder {
|
|
|
4455
4502
|
}
|
|
4456
4503
|
}
|
|
4457
4504
|
|
|
4505
|
+
const conditionExports = pluginPermissionNode.createConditionExports({
|
|
4506
|
+
pluginId: "catalog",
|
|
4507
|
+
resourceType: pluginCatalogCommon.RESOURCE_TYPE_CATALOG_ENTITY,
|
|
4508
|
+
rules: permissionRules
|
|
4509
|
+
});
|
|
4510
|
+
const catalogConditions = conditionExports.conditions;
|
|
4511
|
+
const createCatalogPolicyDecision = conditionExports.createPolicyDecision;
|
|
4512
|
+
|
|
4458
4513
|
exports.AnnotateLocationEntityProcessor = AnnotateLocationEntityProcessor;
|
|
4459
4514
|
exports.AnnotateScmSlugEntityProcessor = AnnotateScmSlugEntityProcessor;
|
|
4460
4515
|
exports.AwsOrganizationCloudAccountProcessor = AwsOrganizationCloudAccountProcessor;
|
|
@@ -4477,7 +4532,9 @@ exports.LocationEntityProcessor = LocationEntityProcessor;
|
|
|
4477
4532
|
exports.PlaceholderProcessor = PlaceholderProcessor;
|
|
4478
4533
|
exports.StaticLocationProcessor = StaticLocationProcessor;
|
|
4479
4534
|
exports.UrlReaderProcessor = UrlReaderProcessor;
|
|
4535
|
+
exports.catalogConditions = catalogConditions;
|
|
4480
4536
|
exports.createCatalogPermissionRule = createCatalogPermissionRule;
|
|
4537
|
+
exports.createCatalogPolicyDecision = createCatalogPolicyDecision;
|
|
4481
4538
|
exports.createRandomRefreshInterval = createRandomRefreshInterval;
|
|
4482
4539
|
exports.createRouter = createRouter;
|
|
4483
4540
|
exports.durationText = durationText;
|