scaffolder-backend: exported new TemplateEntityProcessor

Co-authored-by: Johan Haals <johan.haals@gmail.com>
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2021-10-05 17:37:10 +02:00
parent 445d222a48
commit 65742aa801
5 changed files with 197 additions and 0 deletions
+2
View File
@@ -36,6 +36,8 @@
"@backstage/config": "^0.1.10",
"@backstage/errors": "^0.1.2",
"@backstage/integration": "^0.6.7",
"@backstage/plugin-catalog-backend": "^0.15.0",
"@backstage/plugin-scaffolder-common": "^0.1.0",
"@backstage/plugin-scaffolder-backend-module-cookiecutter": "^0.1.2",
"@gitbeaker/core": "^30.2.0",
"@gitbeaker/node": "^30.2.0",
+1
View File
@@ -23,3 +23,4 @@
export * from './scaffolder';
export * from './service/router';
export * from './lib/catalog';
export * from './processor';
@@ -0,0 +1,80 @@
/*
* 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 { TemplateEntityProcessor } from './TemplateEntityProcessor';
const mockLocation = { type: 'a', target: 'b' };
const mockEntity: TemplateEntityV1beta3 = {
apiVersion: 'templates.backstage.io/v1beta3',
kind: 'Template',
metadata: { name: 'n' },
spec: {
parameters: {},
steps: [],
type: 'service',
owner: 'o',
},
};
describe('TemplateEntityProcessor', () => {
describe('validateEntityKind', () => {
it('validates the entity kind', async () => {
const processor = new TemplateEntityProcessor();
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 TemplateEntityProcessor();
const emit = jest.fn();
await processor.postProcessEntity(mockEntity, mockLocation, emit);
expect(emit).toBeCalledTimes(2);
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
source: { kind: 'Group', namespace: 'default', name: 'o' },
type: 'ownerOf',
target: { kind: 'Template', namespace: 'default', name: 'n' },
},
});
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
source: { kind: 'Template', namespace: 'default', name: 'n' },
type: 'ownedBy',
target: { kind: 'Group', namespace: 'default', name: 'o' },
},
});
});
});
});
@@ -0,0 +1,97 @@
/*
* 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,
getEntityName,
LocationSpec,
parseEntityRef,
RELATION_OWNED_BY,
RELATION_OWNER_OF,
entityKindSchemaValidator,
} from '@backstage/catalog-model';
import {
CatalogProcessor,
CatalogProcessorEmit,
results,
} from '@backstage/plugin-catalog-backend';
import {
TemplateEntityV1beta3,
templateEntityV1beta3Schema,
} from '@backstage/plugin-scaffolder-common';
export class TemplateEntityProcessor implements CatalogProcessor {
private readonly validators = [
entityKindSchemaValidator(templateEntityV1beta3Schema),
];
async validateEntityKind(entity: Entity): Promise<boolean> {
for (const validator of this.validators) {
if (validator(entity)) {
return true;
}
}
return false;
}
async postProcessEntity(
entity: Entity,
_location: LocationSpec,
emit: CatalogProcessorEmit,
): Promise<Entity> {
const selfRef = getEntityName(entity);
if (
entity.apiVersion === 'templates.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(
results.relation({
source: selfRef,
type: RELATION_OWNED_BY,
target: {
kind: targetRef.kind,
namespace: targetRef.namespace,
name: targetRef.name,
},
}),
);
emit(
results.relation({
source: {
kind: targetRef.kind,
namespace: targetRef.namespace,
name: targetRef.name,
},
type: RELATION_OWNER_OF,
target: selfRef,
}),
);
}
}
return entity;
}
}
@@ -0,0 +1,17 @@
/*
* 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 { TemplateEntityProcessor } from './TemplateEntityProcessor';