Merge pull request #5155 from jmgrimes/group-members-support
Added support for 'members' field of Group catalog model entity.
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
---
|
||||
'@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-user) (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:
|
||||
|
||||
@@ -39,6 +39,7 @@ describe('GroupV1alpha1Validator', () => {
|
||||
},
|
||||
parent: 'group-a',
|
||||
children: ['child-a', 'child-b'],
|
||||
members: ['jdoe'],
|
||||
},
|
||||
};
|
||||
});
|
||||
@@ -172,4 +173,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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+18
-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,
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user