Merge pull request #4033 from SDA-SE/feat/make-system-and-domains-real

Implement systems, domains and resources
This commit is contained in:
Fredrik Adelöw
2021-01-14 13:44:20 +01:00
committed by GitHub
32 changed files with 809 additions and 6 deletions
@@ -17,7 +17,10 @@
import {
ApiEntity,
ComponentEntity,
DomainEntity,
GroupEntity,
ResourceEntity,
SystemEntity,
UserEntity,
} from '@backstage/catalog-model';
import { BuiltinKindsEntityProcessor } from './BuiltinKindsEntityProcessor';
@@ -42,12 +45,13 @@ describe('BuiltinKindsEntityProcessor', () => {
lifecycle: 'l',
providesApis: ['b'],
consumesApis: ['c'],
system: 's',
},
};
await processor.postProcessEntity(entity, location, emit);
expect(emit).toBeCalledTimes(8);
expect(emit).toBeCalledTimes(10);
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
@@ -112,6 +116,22 @@ describe('BuiltinKindsEntityProcessor', () => {
target: { kind: 'Component', namespace: 'default', name: 's' },
},
});
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
source: { kind: 'System', namespace: 'default', name: 's' },
type: 'hasPart',
target: { kind: 'Component', namespace: 'default', name: 'n' },
},
});
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
source: { kind: 'Component', namespace: 'default', name: 'n' },
type: 'partOf',
target: { kind: 'System', namespace: 'default', name: 's' },
},
});
});
it('generates relations for api entities', async () => {
@@ -124,12 +144,13 @@ describe('BuiltinKindsEntityProcessor', () => {
owner: 'o',
lifecycle: 'l',
definition: 'd',
system: 's',
},
};
await processor.postProcessEntity(entity, location, emit);
expect(emit).toBeCalledTimes(2);
expect(emit).toBeCalledTimes(4);
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
@@ -146,6 +167,150 @@ describe('BuiltinKindsEntityProcessor', () => {
target: { kind: 'Group', namespace: 'default', name: 'o' },
},
});
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
source: { kind: 'System', namespace: 'default', name: 's' },
type: 'hasPart',
target: { kind: 'API', namespace: 'default', name: 'n' },
},
});
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
source: { kind: 'API', namespace: 'default', name: 'n' },
type: 'partOf',
target: { kind: 'System', namespace: 'default', name: 's' },
},
});
});
it('generates relations for resource entities', async () => {
const entity: ResourceEntity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Resource',
metadata: { name: 'n' },
spec: {
type: 'database',
owner: 'o',
system: 's',
},
};
await processor.postProcessEntity(entity, location, emit);
expect(emit).toBeCalledTimes(4);
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
source: { kind: 'Group', namespace: 'default', name: 'o' },
type: 'ownerOf',
target: { kind: 'Resource', namespace: 'default', name: 'n' },
},
});
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
source: { kind: 'Resource', namespace: 'default', name: 'n' },
type: 'ownedBy',
target: { kind: 'Group', namespace: 'default', name: 'o' },
},
});
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
source: { kind: 'System', namespace: 'default', name: 's' },
type: 'hasPart',
target: { kind: 'Resource', namespace: 'default', name: 'n' },
},
});
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
source: { kind: 'Resource', namespace: 'default', name: 'n' },
type: 'partOf',
target: { kind: 'System', namespace: 'default', name: 's' },
},
});
});
it('generates relations for system entities', async () => {
const entity: SystemEntity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'System',
metadata: { name: 'n' },
spec: {
owner: 'o',
domain: 'd',
},
};
await processor.postProcessEntity(entity, location, emit);
expect(emit).toBeCalledTimes(4);
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
source: { kind: 'Group', namespace: 'default', name: 'o' },
type: 'ownerOf',
target: { kind: 'System', namespace: 'default', name: 'n' },
},
});
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
source: { kind: 'System', namespace: 'default', name: 'n' },
type: 'ownedBy',
target: { kind: 'Group', namespace: 'default', name: 'o' },
},
});
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
source: { kind: 'Domain', namespace: 'default', name: 'd' },
type: 'hasPart',
target: { kind: 'System', namespace: 'default', name: 'n' },
},
});
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
source: { kind: 'System', namespace: 'default', name: 'n' },
type: 'partOf',
target: { kind: 'Domain', namespace: 'default', name: 'd' },
},
});
});
it('generates relations for domain entities', async () => {
const entity: DomainEntity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Domain',
metadata: { name: 'n' },
spec: {
owner: 'o',
},
};
await processor.postProcessEntity(entity, location, emit);
expect(emit).toBeCalledTimes(2);
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
source: { kind: 'Group', namespace: 'default', name: 'o' },
type: 'ownerOf',
target: { kind: 'Domain', namespace: 'default', name: 'n' },
},
});
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
source: { kind: 'Domain', namespace: 'default', name: 'n' },
type: 'ownedBy',
target: { kind: 'Group', namespace: 'default', name: 'o' },
},
});
});
it('generates relations for user entities', async () => {
@@ -19,6 +19,8 @@ import {
apiEntityV1alpha1Validator,
ComponentEntity,
componentEntityV1alpha1Validator,
DomainEntity,
domainEntityV1alpha1Validator,
Entity,
getEntityName,
GroupEntity,
@@ -31,13 +33,17 @@ import {
RELATION_CHILD_OF,
RELATION_CONSUMES_API,
RELATION_HAS_MEMBER,
RELATION_MEMBER_OF,
RELATION_HAS_PART,
RELATION_PART_OF,
RELATION_MEMBER_OF,
RELATION_OWNED_BY,
RELATION_OWNER_OF,
RELATION_PARENT_OF,
RELATION_PART_OF,
RELATION_PROVIDES_API,
ResourceEntity,
resourceEntityV1alpha1Validator,
SystemEntity,
systemEntityV1alpha1Validator,
templateEntityV1alpha1Validator,
UserEntity,
userEntityV1alpha1Validator,
@@ -49,10 +55,13 @@ export class BuiltinKindsEntityProcessor implements CatalogProcessor {
private readonly validators = [
apiEntityV1alpha1Validator,
componentEntityV1alpha1Validator,
resourceEntityV1alpha1Validator,
groupEntityV1alpha1Validator,
locationEntityV1alpha1Validator,
templateEntityV1alpha1Validator,
userEntityV1alpha1Validator,
systemEntityV1alpha1Validator,
domainEntityV1alpha1Validator,
];
async validateEntityKind(entity: Entity): Promise<boolean> {
@@ -135,6 +144,12 @@ export class BuiltinKindsEntityProcessor implements CatalogProcessor {
RELATION_CONSUMES_API,
RELATION_API_CONSUMED_BY,
);
doEmit(
component.spec.system,
{ defaultKind: 'System', defaultNamespace: selfRef.namespace },
RELATION_PART_OF,
RELATION_HAS_PART,
);
}
/*
@@ -149,6 +164,32 @@ export class BuiltinKindsEntityProcessor implements CatalogProcessor {
RELATION_OWNED_BY,
RELATION_OWNER_OF,
);
doEmit(
api.spec.system,
{ defaultKind: 'System', defaultNamespace: selfRef.namespace },
RELATION_PART_OF,
RELATION_HAS_PART,
);
}
/*
* Emit relations for the Resource kind
*/
if (entity.kind === 'Resource') {
const resource = entity as ResourceEntity;
doEmit(
resource.spec.owner,
{ defaultKind: 'Group', defaultNamespace: selfRef.namespace },
RELATION_OWNED_BY,
RELATION_OWNER_OF,
);
doEmit(
resource.spec.system,
{ defaultKind: 'System', defaultNamespace: selfRef.namespace },
RELATION_PART_OF,
RELATION_HAS_PART,
);
}
/*
@@ -185,6 +226,40 @@ export class BuiltinKindsEntityProcessor implements CatalogProcessor {
);
}
/*
* Emit relations for the System kind
*/
if (entity.kind === 'System') {
const system = entity as SystemEntity;
doEmit(
system.spec.owner,
{ defaultKind: 'Group', defaultNamespace: selfRef.namespace },
RELATION_OWNED_BY,
RELATION_OWNER_OF,
);
doEmit(
system.spec.domain,
{ defaultKind: 'Domain', defaultNamespace: selfRef.namespace },
RELATION_PART_OF,
RELATION_HAS_PART,
);
}
/*
* Emit relations for the Domain kind
*/
if (entity.kind === 'Domain') {
const domain = entity as DomainEntity;
doEmit(
domain.spec.owner,
{ defaultKind: 'Group', defaultNamespace: selfRef.namespace },
RELATION_OWNED_BY,
RELATION_OWNER_OF,
);
}
return entity;
}
}