removed dependencyOf reverse specification of dependencies, added dependsOn support at the Resource entity level, removed default entity reference kind for dependsOn, updated documentation

Signed-off-by: Jonah Grimes <jonah.grimes@gmail.com>
This commit is contained in:
Jonah Grimes
2021-03-31 10:01:39 -04:00
parent c8b60c4b4d
commit d5e059a3c8
7 changed files with 131 additions and 37 deletions
@@ -45,14 +45,14 @@ describe('BuiltinKindsEntityProcessor', () => {
lifecycle: 'l',
providesApis: ['b'],
consumesApis: ['c'],
dependsOn: ['r'],
dependsOn: ['Resource:r', 'Component:d'],
system: 's',
},
};
await processor.postProcessEntity(entity, location, emit);
expect(emit).toBeCalledTimes(12);
expect(emit).toBeCalledTimes(14);
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
@@ -101,6 +101,14 @@ describe('BuiltinKindsEntityProcessor', () => {
target: { kind: 'API', namespace: 'default', name: 'c' },
},
});
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
source: { kind: 'Component', namespace: 'default', name: 'n' },
type: 'dependsOn',
target: { kind: 'Resource', namespace: 'default', name: 'r' },
},
});
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
@@ -114,7 +122,15 @@ describe('BuiltinKindsEntityProcessor', () => {
relation: {
source: { kind: 'Component', namespace: 'default', name: 'n' },
type: 'dependsOn',
target: { kind: 'Resource', namespace: 'default', name: 'r' },
target: { kind: 'Component', namespace: 'default', name: 'd' },
},
});
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
source: { kind: 'Component', namespace: 'default', name: 'd' },
type: 'dependencyOf',
target: { kind: 'Component', namespace: 'default', name: 'n' },
},
});
expect(emit).toBeCalledWith({
@@ -151,6 +167,29 @@ describe('BuiltinKindsEntityProcessor', () => {
});
});
it('generates an error for component entities with unspecified dependsOn entity reference kinds', async () => {
const entity: ComponentEntity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: { name: 'n' },
spec: {
type: 'service',
owner: 'o',
subcomponentOf: 's',
lifecycle: 'l',
providesApis: ['b'],
consumesApis: ['c'],
dependsOn: ['r'],
system: 's',
},
};
await expect(
processor.postProcessEntity(entity, location, emit),
).rejects.toThrowError(
'Entity reference kind is undefined and has no default',
);
});
it('generates relations for api entities', async () => {
const entity: ApiEntity = {
apiVersion: 'backstage.io/v1alpha1',
@@ -210,14 +249,14 @@ describe('BuiltinKindsEntityProcessor', () => {
spec: {
type: 'database',
owner: 'o',
dependencyOf: ['c'],
dependsOn: ['Component:c', 'Resource:r'],
system: 's',
},
};
await processor.postProcessEntity(entity, location, emit);
expect(emit).toBeCalledTimes(6);
expect(emit).toBeCalledTimes(8);
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
@@ -234,11 +273,12 @@ describe('BuiltinKindsEntityProcessor', () => {
target: { kind: 'Group', namespace: 'default', name: 'o' },
},
});
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
source: { kind: 'Resource', namespace: 'default', name: 'n' },
type: 'dependencyOf',
type: 'dependsOn',
target: { kind: 'Component', namespace: 'default', name: 'c' },
},
});
@@ -246,10 +286,28 @@ describe('BuiltinKindsEntityProcessor', () => {
type: 'relation',
relation: {
source: { kind: 'Component', namespace: 'default', name: 'c' },
type: 'dependsOn',
type: 'dependencyOf',
target: { kind: 'Resource', namespace: 'default', name: 'n' },
},
});
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
source: { kind: 'Resource', namespace: 'default', name: 'n' },
type: 'dependsOn',
target: { kind: 'Resource', namespace: 'default', name: 'r' },
},
});
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
source: { kind: 'Resource', namespace: 'default', name: 'r' },
type: 'dependencyOf',
target: { kind: 'Resource', namespace: 'default', name: 'n' },
},
});
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
@@ -268,6 +326,25 @@ describe('BuiltinKindsEntityProcessor', () => {
});
});
it('generates an error for resource entities with unspecified dependsOn entity reference kinds', async () => {
const entity: ResourceEntity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Resource',
metadata: { name: 'n' },
spec: {
type: 'database',
owner: 'o',
dependsOn: ['r'],
system: 's',
},
};
await expect(
processor.postProcessEntity(entity, location, emit),
).rejects.toThrowError(
'Entity reference kind is undefined and has no default',
);
});
it('generates relations for system entities', async () => {
const entity: SystemEntity = {
apiVersion: 'backstage.io/v1alpha1',
@@ -92,7 +92,7 @@ export class BuiltinKindsEntityProcessor implements CatalogProcessor {
function doEmit(
targets: string | string[] | undefined,
context: { defaultKind: string; defaultNamespace: string },
context: { defaultKind?: string; defaultNamespace: string },
outgoingRelation: string,
incomingRelation: string,
): void {
@@ -101,16 +101,29 @@ export class BuiltinKindsEntityProcessor implements CatalogProcessor {
}
for (const target of [targets].flat()) {
const targetRef = parseEntityRef(target, context);
if (targetRef.kind === undefined) {
throw new Error(
'Entity reference kind is undefined and has no default',
);
}
emit(
result.relation({
source: selfRef,
type: outgoingRelation,
target: targetRef,
target: {
kind: targetRef.kind,
namespace: targetRef.namespace,
name: targetRef.name,
},
}),
);
emit(
result.relation({
source: targetRef,
source: {
kind: targetRef.kind,
namespace: targetRef.namespace,
name: targetRef.name,
},
type: incomingRelation,
target: selfRef,
}),
@@ -150,7 +163,7 @@ export class BuiltinKindsEntityProcessor implements CatalogProcessor {
);
doEmit(
component.spec.dependsOn,
{ defaultKind: 'Resource', defaultNamespace: selfRef.namespace },
{ defaultNamespace: selfRef.namespace },
RELATION_DEPENDS_ON,
RELATION_DEPENDENCY_OF,
);
@@ -195,10 +208,10 @@ export class BuiltinKindsEntityProcessor implements CatalogProcessor {
RELATION_OWNER_OF,
);
doEmit(
resource.spec.dependencyOf,
{ defaultKind: 'Component', defaultNamespace: selfRef.namespace },
RELATION_DEPENDENCY_OF,
resource.spec.dependsOn,
{ defaultNamespace: selfRef.namespace },
RELATION_DEPENDS_ON,
RELATION_DEPENDENCY_OF,
);
doEmit(
resource.spec.system,