Moved ScaffolderEntitiesProcessor and catalogModuleTemplateKind to a dedicated module
Signed-off-by: Fredrik Adelöw <freben@gmail.com> Co-authored-by: Camila Belo <camilaibs@gmail.com> Co-authored-by: Philipp Hugenroth <philipph@spotify.com> Co-authored-by: Patrik Oldsberg <poldsberg@gmail.com> Co-authored-by: Johan Haals <johan.haals@gmail.com>
This commit is contained in:
@@ -15,9 +15,6 @@ import { ResourcePermission } from '@backstage/plugin-permission-common';
|
||||
import { TemplateEntityStepV1beta3 } from '@backstage/plugin-scaffolder-common';
|
||||
import { TemplateParametersV1beta3 } from '@backstage/plugin-scaffolder-common';
|
||||
|
||||
// @alpha
|
||||
export const catalogModuleTemplateKind: () => BackendFeature;
|
||||
|
||||
// @alpha (undocumented)
|
||||
export const createScaffolderActionConditionalDecision: (
|
||||
permission: ResourcePermission<'scaffolder-action'>,
|
||||
|
||||
@@ -5,12 +5,9 @@
|
||||
```ts
|
||||
import { ActionContext as ActionContext_2 } from '@backstage/plugin-scaffolder-node';
|
||||
import { CatalogApi } from '@backstage/catalog-client';
|
||||
import { CatalogProcessor } from '@backstage/plugin-catalog-node';
|
||||
import { CatalogProcessorEmit } from '@backstage/plugin-catalog-node';
|
||||
import { Config } from '@backstage/config';
|
||||
import { createPullRequest } from 'octokit-plugin-create-pull-request';
|
||||
import { Duration } from 'luxon';
|
||||
import { Entity } from '@backstage/catalog-model';
|
||||
import { executeShellCommand as executeShellCommand_2 } from '@backstage/plugin-scaffolder-node';
|
||||
import { ExecuteShellCommandOptions } from '@backstage/plugin-scaffolder-node';
|
||||
import express from 'express';
|
||||
@@ -20,7 +17,6 @@ import { HumanDuration } from '@backstage/types';
|
||||
import { IdentityApi } from '@backstage/plugin-auth-node';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import { Knex } from 'knex';
|
||||
import { LocationSpec } from '@backstage/plugin-catalog-common';
|
||||
import { Logger } from 'winston';
|
||||
import { Octokit } from 'octokit';
|
||||
import { PermissionEvaluator } from '@backstage/plugin-permission-common';
|
||||
@@ -30,6 +26,7 @@ import { PluginDatabaseManager } from '@backstage/backend-common';
|
||||
import { PluginTaskScheduler } from '@backstage/backend-tasks';
|
||||
import { RESOURCE_TYPE_SCAFFOLDER_ACTION } from '@backstage/plugin-scaffolder-common/alpha';
|
||||
import { RESOURCE_TYPE_SCAFFOLDER_TEMPLATE } from '@backstage/plugin-scaffolder-common/alpha';
|
||||
import { ScaffolderEntitiesProcessor as ScaffolderEntitiesProcessor_2 } from '@backstage/plugin-catalog-backend-module-scaffolder-entities';
|
||||
import { Schema } from 'jsonschema';
|
||||
import { ScmIntegrationRegistry } from '@backstage/integration';
|
||||
import { ScmIntegrations } from '@backstage/integration';
|
||||
@@ -881,19 +878,8 @@ export interface RouterOptions {
|
||||
// @public @deprecated
|
||||
export type RunCommandOptions = ExecuteShellCommandOptions;
|
||||
|
||||
// @public (undocumented)
|
||||
export class ScaffolderEntitiesProcessor implements CatalogProcessor {
|
||||
// (undocumented)
|
||||
getProcessorName(): string;
|
||||
// (undocumented)
|
||||
postProcessEntity(
|
||||
entity: Entity,
|
||||
_location: LocationSpec,
|
||||
emit: CatalogProcessorEmit,
|
||||
): Promise<Entity>;
|
||||
// (undocumented)
|
||||
validateEntityKind(entity: Entity): Promise<boolean>;
|
||||
}
|
||||
// @public @deprecated
|
||||
export const ScaffolderEntitiesProcessor: typeof ScaffolderEntitiesProcessor_2;
|
||||
|
||||
// @public @deprecated
|
||||
export type SerializedTask = SerializedTask_2;
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
"@backstage/integration": "workspace:^",
|
||||
"@backstage/plugin-auth-node": "workspace:^",
|
||||
"@backstage/plugin-catalog-backend": "workspace:^",
|
||||
"@backstage/plugin-catalog-backend-module-scaffolder-entities": "workspace:^",
|
||||
"@backstage/plugin-catalog-common": "workspace:^",
|
||||
"@backstage/plugin-catalog-node": "workspace:^",
|
||||
"@backstage/plugin-permission-common": "workspace:^",
|
||||
|
||||
@@ -14,6 +14,5 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export * from './modules';
|
||||
export * from './service';
|
||||
export { scaffolderPlugin as default } from './ScaffolderPlugin';
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
fetchContents as fetchContentsNode,
|
||||
} from '@backstage/plugin-scaffolder-node';
|
||||
import { JsonObject } from '@backstage/types';
|
||||
import { ScaffolderEntitiesProcessor as ScaffolderEntitiesProcessorModule } from '@backstage/plugin-catalog-backend-module-scaffolder-entities';
|
||||
|
||||
/**
|
||||
* @public
|
||||
@@ -75,3 +76,11 @@ export const executeShellCommand = executeShellCommandNode;
|
||||
* @deprecated Use `fetchContents` from `@backstage/plugin-scaffolder-node` instead
|
||||
*/
|
||||
export const fetchContents = fetchContentsNode;
|
||||
|
||||
/**
|
||||
* Adds support for scaffolder specific entity kinds to the catalog.
|
||||
*
|
||||
* @public
|
||||
* @deprecated Import from `@backstage/plugin-catalog-backend-module-scaffolder-entities` instead
|
||||
*/
|
||||
export const ScaffolderEntitiesProcessor = ScaffolderEntitiesProcessorModule;
|
||||
|
||||
@@ -23,6 +23,5 @@
|
||||
export * from './scaffolder';
|
||||
export * from './service/router';
|
||||
export * from './lib';
|
||||
export * from './processor';
|
||||
|
||||
export * from './deprecated';
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha';
|
||||
import { ScaffolderEntitiesProcessor } from '../processor';
|
||||
import { catalogModuleTemplateKind } from './catalogModuleTemplateKind';
|
||||
import { startTestBackend } from '@backstage/backend-test-utils';
|
||||
|
||||
describe('catalogModuleTemplateKind', () => {
|
||||
it('should register the extension point', async () => {
|
||||
const extensionPoint = { addProcessor: jest.fn() };
|
||||
await startTestBackend({
|
||||
extensionPoints: [[catalogProcessingExtensionPoint, extensionPoint]],
|
||||
features: [catalogModuleTemplateKind()],
|
||||
});
|
||||
|
||||
expect(extensionPoint.addProcessor).toHaveBeenCalledWith(
|
||||
new ScaffolderEntitiesProcessor(),
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createBackendModule } from '@backstage/backend-plugin-api';
|
||||
import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha';
|
||||
import { ScaffolderEntitiesProcessor } from '../processor';
|
||||
|
||||
/**
|
||||
* Registers support for the Template kind to the catalog backend plugin.
|
||||
*
|
||||
* @alpha
|
||||
*/
|
||||
export const catalogModuleTemplateKind = createBackendModule({
|
||||
moduleId: 'templateKind',
|
||||
pluginId: 'catalog',
|
||||
register(env) {
|
||||
env.registerInit({
|
||||
deps: {
|
||||
catalog: catalogProcessingExtensionPoint,
|
||||
},
|
||||
async init({ catalog }) {
|
||||
catalog.addProcessor(new ScaffolderEntitiesProcessor());
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
@@ -1,17 +0,0 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { catalogModuleTemplateKind } from './catalogModuleTemplateKind';
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common';
|
||||
import { ScaffolderEntitiesProcessor } from './ScaffolderEntitiesProcessor';
|
||||
|
||||
const mockLocation = { type: 'a', target: 'b' };
|
||||
const mockEntity: TemplateEntityV1beta3 = {
|
||||
apiVersion: 'scaffolder.backstage.io/v1beta3',
|
||||
kind: 'Template',
|
||||
metadata: { name: 'n' },
|
||||
spec: {
|
||||
parameters: {},
|
||||
steps: [],
|
||||
type: 'service',
|
||||
owner: 'o',
|
||||
},
|
||||
};
|
||||
|
||||
describe('ScaffolderEntitiesProcessor', () => {
|
||||
describe('validateEntityKind', () => {
|
||||
it('validates the entity kind', async () => {
|
||||
const processor = new ScaffolderEntitiesProcessor();
|
||||
|
||||
await expect(processor.validateEntityKind(mockEntity)).resolves.toBe(
|
||||
true,
|
||||
);
|
||||
await expect(
|
||||
processor.validateEntityKind({
|
||||
...mockEntity,
|
||||
apiVersion: 'backstage.io/v1beta3',
|
||||
}),
|
||||
).resolves.toBe(false);
|
||||
await expect(
|
||||
processor.validateEntityKind({ ...mockEntity, kind: 'Component' }),
|
||||
).resolves.toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('postProcessEntity', () => {
|
||||
it('generates relations for component entities', async () => {
|
||||
const processor = new ScaffolderEntitiesProcessor();
|
||||
|
||||
const emit = jest.fn();
|
||||
|
||||
await processor.postProcessEntity(mockEntity, mockLocation, emit);
|
||||
|
||||
expect(emit).toHaveBeenCalledTimes(2);
|
||||
expect(emit).toHaveBeenCalledWith({
|
||||
type: 'relation',
|
||||
relation: {
|
||||
source: { kind: 'Group', namespace: 'default', name: 'o' },
|
||||
type: 'ownerOf',
|
||||
target: { kind: 'Template', namespace: 'default', name: 'n' },
|
||||
},
|
||||
});
|
||||
expect(emit).toHaveBeenCalledWith({
|
||||
type: 'relation',
|
||||
relation: {
|
||||
source: { kind: 'Template', namespace: 'default', name: 'n' },
|
||||
type: 'ownedBy',
|
||||
target: { kind: 'Group', namespace: 'default', name: 'o' },
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright 2020 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
Entity,
|
||||
getCompoundEntityRef,
|
||||
parseEntityRef,
|
||||
RELATION_OWNED_BY,
|
||||
RELATION_OWNER_OF,
|
||||
} from '@backstage/catalog-model';
|
||||
import {
|
||||
CatalogProcessor,
|
||||
CatalogProcessorEmit,
|
||||
processingResult,
|
||||
} from '@backstage/plugin-catalog-node';
|
||||
import { LocationSpec } from '@backstage/plugin-catalog-common';
|
||||
import {
|
||||
TemplateEntityV1beta3,
|
||||
templateEntityV1beta3Validator,
|
||||
} from '@backstage/plugin-scaffolder-common';
|
||||
|
||||
/** @public */
|
||||
export class ScaffolderEntitiesProcessor implements CatalogProcessor {
|
||||
getProcessorName(): string {
|
||||
return 'ScaffolderEntitiesProcessor';
|
||||
}
|
||||
|
||||
private readonly validators = [templateEntityV1beta3Validator];
|
||||
|
||||
async validateEntityKind(entity: Entity): Promise<boolean> {
|
||||
for (const validator of this.validators) {
|
||||
if (await validator.check(entity)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
async postProcessEntity(
|
||||
entity: Entity,
|
||||
_location: LocationSpec,
|
||||
emit: CatalogProcessorEmit,
|
||||
): Promise<Entity> {
|
||||
const selfRef = getCompoundEntityRef(entity);
|
||||
|
||||
if (
|
||||
entity.apiVersion === 'scaffolder.backstage.io/v1beta3' &&
|
||||
entity.kind === 'Template'
|
||||
) {
|
||||
const template = entity as TemplateEntityV1beta3;
|
||||
|
||||
const target = template.spec.owner;
|
||||
if (target) {
|
||||
const targetRef = parseEntityRef(target, {
|
||||
defaultKind: 'Group',
|
||||
defaultNamespace: selfRef.namespace,
|
||||
});
|
||||
emit(
|
||||
processingResult.relation({
|
||||
source: selfRef,
|
||||
type: RELATION_OWNED_BY,
|
||||
target: {
|
||||
kind: targetRef.kind,
|
||||
namespace: targetRef.namespace,
|
||||
name: targetRef.name,
|
||||
},
|
||||
}),
|
||||
);
|
||||
emit(
|
||||
processingResult.relation({
|
||||
source: {
|
||||
kind: targetRef.kind,
|
||||
namespace: targetRef.namespace,
|
||||
name: targetRef.name,
|
||||
},
|
||||
type: RELATION_OWNER_OF,
|
||||
target: selfRef,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { ScaffolderEntitiesProcessor } from './ScaffolderEntitiesProcessor';
|
||||
Reference in New Issue
Block a user