@backstage/plugin-catalog-backend 1.26.0-next.2 → 1.26.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 +35 -0
- package/alpha/package.json +1 -1
- package/dist/alpha.cjs.js +2 -2
- package/dist/cjs/{CatalogBuilder-DeLH-BIi.cjs.js → CatalogBuilder-CGSl8LEN.cjs.js} +98 -29
- package/dist/cjs/CatalogBuilder-CGSl8LEN.cjs.js.map +1 -0
- package/dist/index.cjs.js +2 -2
- package/package.json +16 -16
- package/dist/cjs/CatalogBuilder-DeLH-BIi.cjs.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# @backstage/plugin-catalog-backend
|
|
2
2
|
|
|
3
|
+
## 1.26.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 74acf06: Add `dependencyOf` prop to catalog model for Component kind to enable building relationship graphs with both directions using `dependsOn` and `dependencyOf`.
|
|
8
|
+
- 78475c3: Allow offset mode paging in entity list provider
|
|
9
|
+
- bd35cdb: The `analyze-location` endpoint is now protected by the `catalog.location.analyze` permission.
|
|
10
|
+
The `validate-entity` endpoint is now protected by the `catalog.entity.validate` permission.
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- 1882cfe: Moved `getEntities` ordering to utilize database instead of having it inside catalog client
|
|
15
|
+
|
|
16
|
+
Please note that the latest version of `@backstage/catalog-client` will not order the entities in the same way as before. This is because the ordering is now done in the database query instead of in the client. If you rely on the ordering of the entities, you may need to update your backend plugin or code to handle this change.
|
|
17
|
+
|
|
18
|
+
- d425fc4: Modules, plugins, and services are now `BackendFeature`, not a function that returns a feature.
|
|
19
|
+
- c2b63ab: Updated dependency `supertest` to `^7.0.0`.
|
|
20
|
+
- 53cce86: Fixed an issue with the by-query call, where ordering by a field that does not exist on all entities led to not all results being returned
|
|
21
|
+
- Updated dependencies
|
|
22
|
+
- @backstage/backend-common@0.25.0
|
|
23
|
+
- @backstage/backend-plugin-api@1.0.0
|
|
24
|
+
- @backstage/catalog-model@1.7.0
|
|
25
|
+
- @backstage/catalog-client@1.7.0
|
|
26
|
+
- @backstage/plugin-search-backend-module-catalog@0.2.2
|
|
27
|
+
- @backstage/plugin-permission-node@0.8.3
|
|
28
|
+
- @backstage/plugin-catalog-common@1.1.0
|
|
29
|
+
- @backstage/plugin-catalog-node@1.13.0
|
|
30
|
+
- @backstage/integration@1.15.0
|
|
31
|
+
- @backstage/backend-openapi-utils@0.1.18
|
|
32
|
+
- @backstage/plugin-events-node@0.4.0
|
|
33
|
+
- @backstage/config@1.2.0
|
|
34
|
+
- @backstage/errors@1.2.4
|
|
35
|
+
- @backstage/types@1.1.1
|
|
36
|
+
- @backstage/plugin-permission-common@0.8.1
|
|
37
|
+
|
|
3
38
|
## 1.26.0-next.2
|
|
4
39
|
|
|
5
40
|
### Minor Changes
|
package/alpha/package.json
CHANGED
package/dist/alpha.cjs.js
CHANGED
|
@@ -4,7 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var alpha = require('@backstage/plugin-catalog-common/alpha');
|
|
6
6
|
var pluginPermissionNode = require('@backstage/plugin-permission-node');
|
|
7
|
-
var CatalogBuilder = require('./cjs/CatalogBuilder-
|
|
7
|
+
var CatalogBuilder = require('./cjs/CatalogBuilder-CGSl8LEN.cjs.js');
|
|
8
8
|
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
9
9
|
var pluginEventsNode = require('@backstage/plugin-events-node');
|
|
10
10
|
var alpha$1 = require('@backstage/plugin-catalog-node/alpha');
|
|
@@ -25,6 +25,7 @@ require('util');
|
|
|
25
25
|
require('yaml');
|
|
26
26
|
require('p-limit');
|
|
27
27
|
require('uuid');
|
|
28
|
+
require('@backstage/plugin-permission-common');
|
|
28
29
|
require('luxon');
|
|
29
30
|
require('prom-client');
|
|
30
31
|
require('@opentelemetry/api');
|
|
@@ -36,7 +37,6 @@ require('@backstage/types');
|
|
|
36
37
|
require('@backstage/catalog-client');
|
|
37
38
|
require('yn');
|
|
38
39
|
require('@backstage/backend-openapi-utils');
|
|
39
|
-
require('@backstage/plugin-permission-common');
|
|
40
40
|
require('minimatch');
|
|
41
41
|
require('@backstage/config');
|
|
42
42
|
|
|
@@ -17,6 +17,8 @@ var util = require('util');
|
|
|
17
17
|
var yaml = require('yaml');
|
|
18
18
|
var limiterFactory = require('p-limit');
|
|
19
19
|
var uuid = require('uuid');
|
|
20
|
+
var alpha = require('@backstage/plugin-catalog-common/alpha');
|
|
21
|
+
var pluginPermissionCommon = require('@backstage/plugin-permission-common');
|
|
20
22
|
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
21
23
|
var luxon = require('luxon');
|
|
22
24
|
var promClient = require('prom-client');
|
|
@@ -29,8 +31,6 @@ var types = require('@backstage/types');
|
|
|
29
31
|
var catalogClient = require('@backstage/catalog-client');
|
|
30
32
|
var yn = require('yn');
|
|
31
33
|
var backendOpenapiUtils = require('@backstage/backend-openapi-utils');
|
|
32
|
-
var alpha = require('@backstage/plugin-catalog-common/alpha');
|
|
33
|
-
var pluginPermissionCommon = require('@backstage/plugin-permission-common');
|
|
34
34
|
var minimatch = require('minimatch');
|
|
35
35
|
var config = require('@backstage/config');
|
|
36
36
|
var pluginPermissionNode = require('@backstage/plugin-permission-node');
|
|
@@ -317,6 +317,12 @@ class BuiltinKindsEntityProcessor {
|
|
|
317
317
|
catalogModel.RELATION_DEPENDS_ON,
|
|
318
318
|
catalogModel.RELATION_DEPENDENCY_OF
|
|
319
319
|
);
|
|
320
|
+
doEmit(
|
|
321
|
+
component.spec.dependencyOf,
|
|
322
|
+
{ defaultNamespace: selfRef.namespace },
|
|
323
|
+
catalogModel.RELATION_DEPENDENCY_OF,
|
|
324
|
+
catalogModel.RELATION_DEPENDS_ON
|
|
325
|
+
);
|
|
320
326
|
doEmit(
|
|
321
327
|
component.spec.system,
|
|
322
328
|
{ defaultKind: "System", defaultNamespace: selfRef.namespace },
|
|
@@ -1045,6 +1051,27 @@ class RepoLocationAnalyzer {
|
|
|
1045
1051
|
}
|
|
1046
1052
|
}
|
|
1047
1053
|
|
|
1054
|
+
class AuthorizedLocationAnalyzer {
|
|
1055
|
+
constructor(service, permissionApi) {
|
|
1056
|
+
this.service = service;
|
|
1057
|
+
this.permissionApi = permissionApi;
|
|
1058
|
+
}
|
|
1059
|
+
async analyzeLocation(request, credentials) {
|
|
1060
|
+
const authorizeDecision = (await this.permissionApi.authorize(
|
|
1061
|
+
[
|
|
1062
|
+
{
|
|
1063
|
+
permission: alpha.catalogLocationAnalyzePermission
|
|
1064
|
+
}
|
|
1065
|
+
],
|
|
1066
|
+
{ credentials }
|
|
1067
|
+
))[0];
|
|
1068
|
+
if (authorizeDecision.result !== pluginPermissionCommon.AuthorizeResult.ALLOW) {
|
|
1069
|
+
throw new errors.NotAllowedError();
|
|
1070
|
+
}
|
|
1071
|
+
return this.service.analyzeLocation(request, credentials);
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1048
1075
|
function timestampToDateTime(input) {
|
|
1049
1076
|
try {
|
|
1050
1077
|
if (typeof input === "object") {
|
|
@@ -3768,7 +3795,7 @@ function parseEntityFilterString(filterString) {
|
|
|
3768
3795
|
if (!statements.length) {
|
|
3769
3796
|
return void 0;
|
|
3770
3797
|
}
|
|
3771
|
-
const filtersByKey =
|
|
3798
|
+
const filtersByKey = /* @__PURE__ */ new Map();
|
|
3772
3799
|
for (const statement of statements) {
|
|
3773
3800
|
const equalsIndex = statement.indexOf("=");
|
|
3774
3801
|
const key = equalsIndex === -1 ? statement : statement.substring(0, equalsIndex).trim();
|
|
@@ -3778,13 +3805,17 @@ function parseEntityFilterString(filterString) {
|
|
|
3778
3805
|
`Invalid filter, '${statement}' is not a valid statement (expected a string on the form a=b or a= or a)`
|
|
3779
3806
|
);
|
|
3780
3807
|
}
|
|
3781
|
-
|
|
3808
|
+
let f = filtersByKey.get(key);
|
|
3809
|
+
if (!f) {
|
|
3810
|
+
f = { key };
|
|
3811
|
+
filtersByKey.set(key, f);
|
|
3812
|
+
}
|
|
3782
3813
|
if (value !== void 0) {
|
|
3783
3814
|
f.values = f.values || [];
|
|
3784
3815
|
f.values.push(value);
|
|
3785
3816
|
}
|
|
3786
3817
|
}
|
|
3787
|
-
return
|
|
3818
|
+
return Array.from(filtersByKey.values());
|
|
3788
3819
|
}
|
|
3789
3820
|
|
|
3790
3821
|
function getPathArrayAndValue(input, field) {
|
|
@@ -5465,6 +5496,27 @@ function parseEntityPaginationParams({
|
|
|
5465
5496
|
};
|
|
5466
5497
|
}
|
|
5467
5498
|
|
|
5499
|
+
class AuthorizedValidationService {
|
|
5500
|
+
constructor(service, permissionApi) {
|
|
5501
|
+
this.service = service;
|
|
5502
|
+
this.permissionApi = permissionApi;
|
|
5503
|
+
}
|
|
5504
|
+
async process(request, credentials) {
|
|
5505
|
+
const authorizeDecision = (await this.permissionApi.authorize(
|
|
5506
|
+
[
|
|
5507
|
+
{
|
|
5508
|
+
permission: alpha.catalogEntityValidatePermission
|
|
5509
|
+
}
|
|
5510
|
+
],
|
|
5511
|
+
{ credentials }
|
|
5512
|
+
))[0];
|
|
5513
|
+
if (authorizeDecision.result !== pluginPermissionCommon.AuthorizeResult.ALLOW) {
|
|
5514
|
+
throw new errors.NotAllowedError();
|
|
5515
|
+
}
|
|
5516
|
+
return this.service.process(request);
|
|
5517
|
+
}
|
|
5518
|
+
}
|
|
5519
|
+
|
|
5468
5520
|
async function createRouter(options) {
|
|
5469
5521
|
const router = await createOpenApiRouter({
|
|
5470
5522
|
validatorOptions: {
|
|
@@ -5482,6 +5534,7 @@ async function createRouter(options) {
|
|
|
5482
5534
|
config,
|
|
5483
5535
|
logger,
|
|
5484
5536
|
permissionIntegrationRouter,
|
|
5537
|
+
permissionsService,
|
|
5485
5538
|
auth,
|
|
5486
5539
|
httpAuth
|
|
5487
5540
|
} = options;
|
|
@@ -5649,9 +5702,13 @@ async function createRouter(options) {
|
|
|
5649
5702
|
location: locationInput,
|
|
5650
5703
|
catalogFilename: zod.z.string().optional()
|
|
5651
5704
|
});
|
|
5705
|
+
const credentials = await httpAuth.credentials(req);
|
|
5652
5706
|
const parsedBody = schema.parse(body);
|
|
5653
5707
|
try {
|
|
5654
|
-
const output = await locationAnalyzer.analyzeLocation(
|
|
5708
|
+
const output = await locationAnalyzer.analyzeLocation(
|
|
5709
|
+
parsedBody,
|
|
5710
|
+
credentials
|
|
5711
|
+
);
|
|
5655
5712
|
res.status(200).json(output);
|
|
5656
5713
|
} catch (err) {
|
|
5657
5714
|
if (
|
|
@@ -5686,19 +5743,27 @@ async function createRouter(options) {
|
|
|
5686
5743
|
errors: [errors.serializeError(err)]
|
|
5687
5744
|
});
|
|
5688
5745
|
}
|
|
5689
|
-
const
|
|
5690
|
-
|
|
5691
|
-
|
|
5692
|
-
|
|
5693
|
-
|
|
5694
|
-
|
|
5695
|
-
|
|
5696
|
-
|
|
5697
|
-
|
|
5746
|
+
const credentials = await httpAuth.credentials(req);
|
|
5747
|
+
const authorizedValidationService = new AuthorizedValidationService(
|
|
5748
|
+
orchestrator,
|
|
5749
|
+
permissionsService
|
|
5750
|
+
);
|
|
5751
|
+
const processingResult = await authorizedValidationService.process(
|
|
5752
|
+
{
|
|
5753
|
+
entity: {
|
|
5754
|
+
...entity,
|
|
5755
|
+
metadata: {
|
|
5756
|
+
...entity.metadata,
|
|
5757
|
+
annotations: {
|
|
5758
|
+
[catalogModel.ANNOTATION_LOCATION]: body.location,
|
|
5759
|
+
[catalogModel.ANNOTATION_ORIGIN_LOCATION]: body.location,
|
|
5760
|
+
...entity.metadata.annotations
|
|
5761
|
+
}
|
|
5698
5762
|
}
|
|
5699
5763
|
}
|
|
5700
|
-
}
|
|
5701
|
-
|
|
5764
|
+
},
|
|
5765
|
+
credentials
|
|
5766
|
+
);
|
|
5702
5767
|
if (!processingResult.ok)
|
|
5703
5768
|
res.status(400).json({
|
|
5704
5769
|
errors: processingResult.errors.map((e) => errors.serializeError(e))
|
|
@@ -7016,15 +7081,6 @@ class CatalogBuilder {
|
|
|
7016
7081
|
});
|
|
7017
7082
|
const integrations = integration.ScmIntegrations.fromConfig(config);
|
|
7018
7083
|
const rulesEnforcer = DefaultCatalogRulesEnforcer.fromConfig(config);
|
|
7019
|
-
const orchestrator = new DefaultCatalogProcessingOrchestrator({
|
|
7020
|
-
processors,
|
|
7021
|
-
integrations,
|
|
7022
|
-
rulesEnforcer,
|
|
7023
|
-
logger,
|
|
7024
|
-
parser,
|
|
7025
|
-
policy,
|
|
7026
|
-
legacySingleProcessorValidation: this.legacySingleProcessorValidation
|
|
7027
|
-
});
|
|
7028
7084
|
const unauthorizedEntitiesCatalog = new DefaultEntitiesCatalog({
|
|
7029
7085
|
database: dbClient,
|
|
7030
7086
|
logger,
|
|
@@ -7039,6 +7095,15 @@ class CatalogBuilder {
|
|
|
7039
7095
|
);
|
|
7040
7096
|
permissionsService = pluginPermissionCommon.toPermissionEvaluator(permissions);
|
|
7041
7097
|
}
|
|
7098
|
+
const orchestrator = new DefaultCatalogProcessingOrchestrator({
|
|
7099
|
+
processors,
|
|
7100
|
+
integrations,
|
|
7101
|
+
rulesEnforcer,
|
|
7102
|
+
logger,
|
|
7103
|
+
parser,
|
|
7104
|
+
policy,
|
|
7105
|
+
legacySingleProcessorValidation: this.legacySingleProcessorValidation
|
|
7106
|
+
});
|
|
7042
7107
|
const entitiesCatalog = new AuthorizedEntitiesCatalog(
|
|
7043
7108
|
unauthorizedEntitiesCatalog,
|
|
7044
7109
|
permissionsService,
|
|
@@ -7089,7 +7154,10 @@ class CatalogBuilder {
|
|
|
7089
7154
|
},
|
|
7090
7155
|
eventBroker: this.eventBroker
|
|
7091
7156
|
});
|
|
7092
|
-
const locationAnalyzer = this.locationAnalyzer ?? new
|
|
7157
|
+
const locationAnalyzer = this.locationAnalyzer ?? new AuthorizedLocationAnalyzer(
|
|
7158
|
+
new RepoLocationAnalyzer(logger, integrations, this.locationAnalyzers),
|
|
7159
|
+
permissionsService
|
|
7160
|
+
);
|
|
7093
7161
|
const locationService = new AuthorizedLocationService(
|
|
7094
7162
|
new DefaultLocationService(locationStore, orchestrator, {
|
|
7095
7163
|
allowedLocationTypes: this.allowedLocationType
|
|
@@ -7110,7 +7178,8 @@ class CatalogBuilder {
|
|
|
7110
7178
|
config,
|
|
7111
7179
|
permissionIntegrationRouter,
|
|
7112
7180
|
auth,
|
|
7113
|
-
httpAuth
|
|
7181
|
+
httpAuth,
|
|
7182
|
+
permissionsService
|
|
7114
7183
|
});
|
|
7115
7184
|
await connectEntityProviders(providerDatabase, entityProviders);
|
|
7116
7185
|
return {
|
|
@@ -7303,4 +7372,4 @@ exports.createCatalogPermissionRule = createCatalogPermissionRule;
|
|
|
7303
7372
|
exports.createRandomProcessingInterval = createRandomProcessingInterval;
|
|
7304
7373
|
exports.parseEntityYaml = parseEntityYaml;
|
|
7305
7374
|
exports.permissionRules = permissionRules;
|
|
7306
|
-
//# sourceMappingURL=CatalogBuilder-
|
|
7375
|
+
//# sourceMappingURL=CatalogBuilder-CGSl8LEN.cjs.js.map
|