added support for the 'members' field of the Group entity, allowing specification of direct members from the Group side of the relationship. added support to the BuiltinKindsEntityProcessor to generate the appropriate relationships. updated documentation.

Signed-off-by: Jonah Grimes <jonah.grimes@gmail.com>
This commit is contained in:
Jonah Grimes
2021-03-28 21:22:36 -04:00
parent 566b549f63
commit 8488a1a969
7 changed files with 75 additions and 1 deletions
+6
View File
@@ -0,0 +1,6 @@
---
'@backstage/catalog-model': patch
'@backstage/plugin-catalog-backend': patch
---
Added support for the "members" field of the Group entity, allowing specification of direct members from the Group side of the relationship. Added support to the BuiltinKindsEntityProcessor to generate the appropriate relationships.
@@ -808,6 +808,7 @@ spec:
picture: https://example.com/groups/bu-infrastructure.jpeg
parent: ops
children: [backstage, other]
members: [jdoe]
```
In addition to the [common envelope metadata](#common-to-all-kinds-the-metadata)
@@ -865,6 +866,18 @@ The entries of this array are
| --------------------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------- |
| [`Group`](#kind-group) (default) | Same as this entity, typically `default` | [`hasMember`, and reverse `memberOf`](well-known-relations.md#memberof-and-hasmember) |
### `spec.members` [optional]
The users that are direct members of this group. The items are not guaranteed to
be ordered in any particular way.
The entries of this array are
[entity references](https://backstage.io/docs/features/software-catalog/references).
| [`kind`](#apiversion-and-kind-required) | Default [`namespace`](#namespace-optional) | Generated [relation](well-known-relations.md) type |
| --------------------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------- |
| [`User`](#kind-group) (default) | Same as this entity, typically `default` | [`hasMember`, and reverse `memberOf`](well-known-relations.md#memberof-and-hasmember) |
## Kind: User
Describes the following entity kind:
@@ -172,4 +172,26 @@ describe('GroupV1alpha1Validator', () => {
(entity as any).spec.children = [];
await expect(validator.check(entity)).resolves.toBe(true);
});
// members
it('accepts missing members', async () => {
delete (entity as any).spec.members;
await expect(validator.check(entity)).resolves.toBe(true);
});
it('rejects empty members', async () => {
(entity as any).spec.members = [''];
await expect(validator.check(entity)).rejects.toThrow(/members/);
});
it('rejects undefined members', async () => {
(entity as any).spec.members = [undefined];
await expect(validator.check(entity)).rejects.toThrow(/members/);
});
it('accepts no members', async () => {
(entity as any).spec.members = [];
await expect(validator.check(entity)).resolves.toBe(true);
});
});
@@ -36,6 +36,7 @@ export interface GroupEntityV1alpha1 extends Entity {
};
parent?: string;
children: string[];
members?: string[];
};
}
@@ -86,6 +86,15 @@
"examples": ["backstage", "other"],
"minLength": 1
}
},
"members": {
"type": "array",
"description": "The users that are members of this group. The entries of this array are entity references.",
"items": {
"type": "string",
"examples": ["jdoe"],
"minLength": 1
}
}
}
}
@@ -353,12 +353,13 @@ describe('BuiltinKindsEntityProcessor', () => {
type: 't',
parent: 'p',
children: ['c'],
members: ['m'],
},
};
await processor.postProcessEntity(entity, location, emit);
expect(emit).toBeCalledTimes(4);
expect(emit).toBeCalledTimes(6);
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
@@ -391,6 +392,22 @@ describe('BuiltinKindsEntityProcessor', () => {
target: { kind: 'Group', namespace: 'default', name: 'c' },
},
});
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
source: { kind: 'User', namespace: 'default', name: 'm' },
type: 'memberOf',
target: { kind: 'Group', namespace: 'default', name: 'n' },
},
});
expect(emit).toBeCalledWith({
type: 'relation',
relation: {
source: { kind: 'Group', namespace: 'default', name: 'n' },
type: 'hasMember',
target: { kind: 'User', namespace: 'default', name: 'm' },
},
});
});
});
});
@@ -226,6 +226,12 @@ export class BuiltinKindsEntityProcessor implements CatalogProcessor {
RELATION_PARENT_OF,
RELATION_CHILD_OF,
);
doEmit(
group.spec.members,
{ defaultKind: 'User', defaultNamespace: selfRef.namespace },
RELATION_HAS_MEMBER,
RELATION_MEMBER_OF,
);
}
/*