From bbfd6bc8ff032d4cfbb06a0cf0a8a0269781a6a7 Mon Sep 17 00:00:00 2001 From: Hghtwr Date: Sun, 10 Nov 2024 21:19:09 +0100 Subject: [PATCH 1/8] extend filter logic to include parent group Signed-off-by: Hghtwr --- .../src/__testUtils__/mocks.ts | 25 ++++++++++++++++++- .../GitlabOrgDiscoveryEntityProvider.ts | 3 ++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts b/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts index 2547015df8..58ba3f10b0 100644 --- a/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts +++ b/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts @@ -2347,7 +2347,7 @@ export const expected_full_members_group_org_scan_entities: MockObject[] = [ name: 'JohnDoe', }, spec: { - memberOf: ['subgroup1'], + memberOf: ['group1', 'subgroup1'], // since #26554 also config.group needs to be here. profile: { displayName: 'John Doe', email: 'john.doe@company.com', @@ -2431,6 +2431,29 @@ export const expected_full_members_group_org_scan_entities: MockObject[] = [ }, locationKey: 'GitlabOrgDiscoveryEntityProvider:test-id', }, + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + annotations: { + 'backstage.io/managed-by-location': 'url:https://example.com/group1', + 'backstage.io/managed-by-origin-location': + 'url:https://example.com/group1', + 'example.com/team-path': 'group1', + }, + name: 'group1', + }, + spec: { + children: [], + profile: { + displayName: 'group1', + }, + type: 'team', + }, + }, + locationKey: 'GitlabOrgDiscoveryEntityProvider:test-id', + }, { entity: { apiVersion: 'backstage.io/v1alpha1', diff --git a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts index 277a5a8c51..f6bb12cdcc 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts @@ -775,7 +775,8 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { return ( this.config.groupPattern.test(group.full_path) && (!this.config.group || - group.full_path.startsWith(`${this.config.group}/`)) + group.full_path.startsWith(`${this.config.group}/`) || + group.full_path === this.config.group) ); } From 1da0abaf53296d447af8379dc37a2d6268d66dd0 Mon Sep 17 00:00:00 2001 From: Hghtwr Date: Fri, 15 Nov 2024 22:47:45 +0100 Subject: [PATCH 2/8] add testing and root group discovery Signed-off-by: Hghtwr --- .../src/__testUtils__/handlers.ts | 8 +++++ .../src/__testUtils__/mocks.ts | 35 +++++++++++++++++-- .../src/lib/client.ts | 10 ++++++ .../GitlabOrgDiscoveryEntityProvider.ts | 3 ++ 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/plugins/catalog-backend-module-gitlab/src/__testUtils__/handlers.ts b/plugins/catalog-backend-module-gitlab/src/__testUtils__/handlers.ts index 953ade6b7c..7dc7829874 100644 --- a/plugins/catalog-backend-module-gitlab/src/__testUtils__/handlers.ts +++ b/plugins/catalog-backend-module-gitlab/src/__testUtils__/handlers.ts @@ -30,6 +30,7 @@ import { some_endpoint, unhealthy_endpoint, userID, + single_group_response, } from './mocks'; const httpHandlers = [ @@ -71,6 +72,9 @@ const httpHandlers = [ return res(ctx.set('x-next-page', ''), ctx.json(all_groups_response)); }), + rest.get(`${apiBaseUrl}/groups/group1`, (_req, res, ctx) => { + return res(ctx.set('x-next-page', ''), ctx.json(single_group_response)); + }), rest.get(`${apiBaseUrl}/groups/42`, (_, res, ctx) => { return res(ctx.status(500), ctx.json({ error: 'Internal Server Error' })); }), @@ -78,6 +82,10 @@ const httpHandlers = [ return res(ctx.json(all_self_hosted_group1_members)); }), + rest.get(`${apiBaseUrlSaas}/groups/group1`, (_req, res, ctx) => { + return res(ctx.set('x-next-page', ''), ctx.json(single_group_response)); + }), + rest.get(`${apiBaseUrlSaas}/groups/group1/members/all`, (_req, res, ctx) => { return res(ctx.json(all_saas_users_response)); }), diff --git a/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts b/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts index 58ba3f10b0..faf44fd031 100644 --- a/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts +++ b/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts @@ -1037,6 +1037,13 @@ export const all_saas_users_response: MockObject[] = [ }, ]; +export const single_group_response: GitLabGroup = { + id: 1, + name: 'group1', + description: 'description1', + full_path: 'group1', +}; + export const all_groups_response: GitLabGroup[] = [ { id: 1, @@ -1111,7 +1118,7 @@ export const expectedSaasGroup: MockObject[] = [ { id: 1, name: 'group1', - description: 'description1', + description: '', full_path: 'path/group1', parent_id: 123, }, @@ -2495,7 +2502,7 @@ export const expected_group_members_group_org_scan_entities: MockObject[] = [ name: 'JohnDoe', }, spec: { - memberOf: ['subgroup1'], + memberOf: ['subgroup1', 'group1'], profile: { displayName: 'John Doe', email: 'john.doe@company.com', @@ -2530,6 +2537,30 @@ export const expected_group_members_group_org_scan_entities: MockObject[] = [ }, locationKey: 'GitlabOrgDiscoveryEntityProvider:test-id', }, + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Group', + metadata: { + annotations: { + 'backstage.io/managed-by-location': 'url:https://example.com/group1', + 'backstage.io/managed-by-origin-location': + 'url:https://example.com/group1', + 'example.com/team-path': 'group1', + }, + name: 'group1', + description: 'description1', + }, + spec: { + children: [], + profile: { + displayName: 'group1', + }, + type: 'team', + }, + }, + locationKey: 'GitlabOrgDiscoveryEntityProvider:test-id', + }, ]; export const all_self_hosted_group1_members: MockObject[] = [ diff --git a/plugins/catalog-backend-module-gitlab/src/lib/client.ts b/plugins/catalog-backend-module-gitlab/src/lib/client.ts index f2ce3d18f8..58dae9ed31 100644 --- a/plugins/catalog-backend-module-gitlab/src/lib/client.ts +++ b/plugins/catalog-backend-module-gitlab/src/lib/client.ts @@ -166,6 +166,16 @@ export class GitLabClient { return this.pagedRequest(`/groups`, options); } + async getGroupByPath( + groupPath: string, + options?: CommonListOptions, + ): Promise { + return this.nonPagedRequest( + `/groups/${encodeURIComponent(groupPath)}`, + options, + ); + } + async listDescendantGroups( groupPath: string, ): Promise> { diff --git a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts index f6bb12cdcc..0293f90a2c 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts @@ -366,6 +366,7 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { if (this.gitLabClient.isSelfManaged() && this.config.restrictUsersToGroup) { groups = (await this.gitLabClient.listDescendantGroups(this.config.group)) .items; + groups.push(await this.gitLabClient.getGroupByPath(this.config.group)); users = paginated( options => this.gitLabClient.listGroupMembers(this.config.group, options), // calls /groups//members @@ -395,10 +396,12 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { else { groups = (await this.gitLabClient.listDescendantGroups(this.config.group)) .items; + groups.push(await this.gitLabClient.getGroupByPath(this.config.group)); const rootGroupSplit = this.config.group.split('/'); const rootGroup = this.config.restrictUsersToGroup ? rootGroupSplit[rootGroupSplit.length - 1] : rootGroupSplit[0]; + users = paginated( options => this.gitLabClient.listSaaSUsers( From 66a88b18c134c0d2336e988b0dd5831f231e7d33 Mon Sep 17 00:00:00 2001 From: Hghtwr Date: Sat, 23 Nov 2024 18:13:52 +0100 Subject: [PATCH 3/8] add handler for encoded groups, implement test cases Signed-off-by: Hghtwr --- .../src/__testUtils__/handlers.ts | 18 +++++++++++++++++- .../src/lib/client.ts | 5 +---- .../GitlabOrgDiscoveryEntityProvider.test.ts | 2 +- .../GitlabOrgDiscoveryEntityProvider.ts | 2 ++ 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/plugins/catalog-backend-module-gitlab/src/__testUtils__/handlers.ts b/plugins/catalog-backend-module-gitlab/src/__testUtils__/handlers.ts index 7dc7829874..9b380891ae 100644 --- a/plugins/catalog-backend-module-gitlab/src/__testUtils__/handlers.ts +++ b/plugins/catalog-backend-module-gitlab/src/__testUtils__/handlers.ts @@ -144,6 +144,21 @@ const httpHandlers = [ // dynamic handlers +const httpGroupFindByEncodedPathDynamic = all_groups_response.flatMap(group => [ + // Handler for apiBaseUrl + rest.get(`${apiBaseUrl}/groups/${group.full_path}`, (_, res, ctx) => { + return res( + ctx.json(all_groups_response.find(g => g.full_path === group.full_path)), + ); + }), + // Handler for apiSaaSBaseUrl + rest.get(`${apiBaseUrlSaas}/groups/${group.full_path}`, (_, res, ctx) => { + return res( + ctx.json(all_groups_response.find(g => g.full_path === group.full_path)), + ); + }), +]); + const httpGroupFindByIdDynamic = all_groups_response.map(group => { return rest.get(`${apiBaseUrl}/groups/${group.id}`, (_, res, ctx) => { return res(ctx.json(all_groups_response.find(g => g.id === group.id))); @@ -491,7 +506,7 @@ const graphqlHandlers = [ { id: 'gid://gitlab/Group/1', name: 'group1', - description: 'description1', + description: '', fullPath: 'path/group1', parent: { id: '123', @@ -626,4 +641,5 @@ export const handlers = [ ...httpGroupListDescendantProjectsById, ...httpGroupListDescendantProjectsByName, ...graphqlHandlers, + ...httpGroupFindByEncodedPathDynamic, ]; diff --git a/plugins/catalog-backend-module-gitlab/src/lib/client.ts b/plugins/catalog-backend-module-gitlab/src/lib/client.ts index 58dae9ed31..1e1d8247cd 100644 --- a/plugins/catalog-backend-module-gitlab/src/lib/client.ts +++ b/plugins/catalog-backend-module-gitlab/src/lib/client.ts @@ -170,10 +170,7 @@ export class GitLabClient { groupPath: string, options?: CommonListOptions, ): Promise { - return this.nonPagedRequest( - `/groups/${encodeURIComponent(groupPath)}`, - options, - ); + return this.nonPagedRequest(`/groups/${groupPath}`, options); } async listDescendantGroups( diff --git a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.test.ts b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.test.ts index a15894b236..5f62cedb71 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.test.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.test.ts @@ -435,7 +435,7 @@ describe('GitlabOrgDiscoveryEntityProvider - refresh', () => { }); // This should return all members of the self-hosted instance regardless of the group set -> expected_full_members_group_org_scan_entities - // All instance members, but only the group entities below the config.group + // All instance members, but only the group entities of config.group and below (#26554) it('Self-hosted: should get all instance users when restrictUsersToGroup is not set', async () => { const config = new ConfigReader(mock.config_org_group_selfHosted); const schedule = new PersistingTaskRunner(); diff --git a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts index 0293f90a2c..556f4ae5a4 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts @@ -396,7 +396,9 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { else { groups = (await this.gitLabClient.listDescendantGroups(this.config.group)) .items; + groups.push(await this.gitLabClient.getGroupByPath(this.config.group)); + const rootGroupSplit = this.config.group.split('/'); const rootGroup = this.config.restrictUsersToGroup ? rootGroupSplit[rootGroupSplit.length - 1] From ab92f94d7a9b777857ef4035193100c6bae15e9d Mon Sep 17 00:00:00 2001 From: Hghtwr Date: Sat, 23 Nov 2024 18:28:13 +0100 Subject: [PATCH 4/8] use consistent group description across all tests, remove unused handler Signed-off-by: Hghtwr --- .../src/__testUtils__/handlers.ts | 10 +--------- .../src/__testUtils__/mocks.ts | 7 +++++-- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/plugins/catalog-backend-module-gitlab/src/__testUtils__/handlers.ts b/plugins/catalog-backend-module-gitlab/src/__testUtils__/handlers.ts index 9b380891ae..752fd08f4b 100644 --- a/plugins/catalog-backend-module-gitlab/src/__testUtils__/handlers.ts +++ b/plugins/catalog-backend-module-gitlab/src/__testUtils__/handlers.ts @@ -30,7 +30,6 @@ import { some_endpoint, unhealthy_endpoint, userID, - single_group_response, } from './mocks'; const httpHandlers = [ @@ -72,9 +71,6 @@ const httpHandlers = [ return res(ctx.set('x-next-page', ''), ctx.json(all_groups_response)); }), - rest.get(`${apiBaseUrl}/groups/group1`, (_req, res, ctx) => { - return res(ctx.set('x-next-page', ''), ctx.json(single_group_response)); - }), rest.get(`${apiBaseUrl}/groups/42`, (_, res, ctx) => { return res(ctx.status(500), ctx.json({ error: 'Internal Server Error' })); }), @@ -82,10 +78,6 @@ const httpHandlers = [ return res(ctx.json(all_self_hosted_group1_members)); }), - rest.get(`${apiBaseUrlSaas}/groups/group1`, (_req, res, ctx) => { - return res(ctx.set('x-next-page', ''), ctx.json(single_group_response)); - }), - rest.get(`${apiBaseUrlSaas}/groups/group1/members/all`, (_req, res, ctx) => { return res(ctx.json(all_saas_users_response)); }), @@ -506,7 +498,7 @@ const graphqlHandlers = [ { id: 'gid://gitlab/Group/1', name: 'group1', - description: '', + description: 'description1', fullPath: 'path/group1', parent: { id: '123', diff --git a/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts b/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts index faf44fd031..e91f015dd3 100644 --- a/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts +++ b/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts @@ -1048,7 +1048,7 @@ export const all_groups_response: GitLabGroup[] = [ { id: 1, name: 'group1', - description: '', + description: 'description1', full_path: 'group1', }, { @@ -1118,7 +1118,7 @@ export const expectedSaasGroup: MockObject[] = [ { id: 1, name: 'group1', - description: '', + description: 'description1', full_path: 'path/group1', parent_id: 123, }, @@ -1811,6 +1811,7 @@ export const expected_group_user_entity: MockObject[] = [ 'url:https://example.com/group1', 'example.com/team-path': 'group1', }, + description: 'description1', name: 'group1', }, spec: { @@ -2097,6 +2098,7 @@ export const expected_full_org_scan_entities: MockObject[] = [ 'url:https://example.com/group1', 'example.com/team-path': 'group1', }, + description: 'description1', name: 'group1', }, spec: { @@ -2449,6 +2451,7 @@ export const expected_full_members_group_org_scan_entities: MockObject[] = [ 'url:https://example.com/group1', 'example.com/team-path': 'group1', }, + description: 'description1', name: 'group1', }, spec: { From ad829efd52fe44c9b98547df71ca2f4d5654a4b2 Mon Sep 17 00:00:00 2001 From: Hghtwr Date: Sat, 23 Nov 2024 20:21:31 +0100 Subject: [PATCH 5/8] add code comments Signed-off-by: Hghtwr --- .../src/__testUtils__/handlers.ts | 1 + plugins/catalog-backend-module-gitlab/src/lib/client.ts | 2 ++ .../src/providers/GitlabOrgDiscoveryEntityProvider.ts | 4 ++-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/catalog-backend-module-gitlab/src/__testUtils__/handlers.ts b/plugins/catalog-backend-module-gitlab/src/__testUtils__/handlers.ts index 752fd08f4b..a4fb3ba391 100644 --- a/plugins/catalog-backend-module-gitlab/src/__testUtils__/handlers.ts +++ b/plugins/catalog-backend-module-gitlab/src/__testUtils__/handlers.ts @@ -136,6 +136,7 @@ const httpHandlers = [ // dynamic handlers +// https://docs.gitlab.com/ee/api/groups.html#list-group-details supports encoded path and id const httpGroupFindByEncodedPathDynamic = all_groups_response.flatMap(group => [ // Handler for apiBaseUrl rest.get(`${apiBaseUrl}/groups/${group.full_path}`, (_, res, ctx) => { diff --git a/plugins/catalog-backend-module-gitlab/src/lib/client.ts b/plugins/catalog-backend-module-gitlab/src/lib/client.ts index 1e1d8247cd..0847587107 100644 --- a/plugins/catalog-backend-module-gitlab/src/lib/client.ts +++ b/plugins/catalog-backend-module-gitlab/src/lib/client.ts @@ -166,6 +166,8 @@ export class GitLabClient { return this.pagedRequest(`/groups`, options); } + // https://docs.gitlab.com/ee/api/groups.html#list-group-details + // id can either be group id or encoded full path async getGroupByPath( groupPath: string, options?: CommonListOptions, diff --git a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts index 556f4ae5a4..eb10dd2274 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts @@ -366,7 +366,7 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { if (this.gitLabClient.isSelfManaged() && this.config.restrictUsersToGroup) { groups = (await this.gitLabClient.listDescendantGroups(this.config.group)) .items; - groups.push(await this.gitLabClient.getGroupByPath(this.config.group)); + groups.push(await this.gitLabClient.getGroupByPath(this.config.group)); // adds the parent group for #26554 users = paginated( options => this.gitLabClient.listGroupMembers(this.config.group, options), // calls /groups//members @@ -397,7 +397,7 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { groups = (await this.gitLabClient.listDescendantGroups(this.config.group)) .items; - groups.push(await this.gitLabClient.getGroupByPath(this.config.group)); + groups.push(await this.gitLabClient.getGroupByPath(this.config.group)); // adds the parent group for #26554 const rootGroupSplit = this.config.group.split('/'); const rootGroup = this.config.restrictUsersToGroup From 0392ad8f77240530fb89bc8683954fcabfa948fc Mon Sep 17 00:00:00 2001 From: Hghtwr Date: Sat, 23 Nov 2024 20:22:46 +0100 Subject: [PATCH 6/8] remove unused response object Signed-off-by: Hghtwr --- .../src/__testUtils__/mocks.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts b/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts index e91f015dd3..d9914c0d0c 100644 --- a/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts +++ b/plugins/catalog-backend-module-gitlab/src/__testUtils__/mocks.ts @@ -1037,13 +1037,6 @@ export const all_saas_users_response: MockObject[] = [ }, ]; -export const single_group_response: GitLabGroup = { - id: 1, - name: 'group1', - description: 'description1', - full_path: 'group1', -}; - export const all_groups_response: GitLabGroup[] = [ { id: 1, From 99dce5cadbd5845ab27a04906bbf65739835c0a0 Mon Sep 17 00:00:00 2001 From: Hghtwr Date: Sat, 23 Nov 2024 20:27:49 +0100 Subject: [PATCH 7/8] add changeset Signed-off-by: Hghtwr --- .changeset/smooth-bikes-sparkle.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/smooth-bikes-sparkle.md diff --git a/.changeset/smooth-bikes-sparkle.md b/.changeset/smooth-bikes-sparkle.md new file mode 100644 index 0000000000..0c1eba172b --- /dev/null +++ b/.changeset/smooth-bikes-sparkle.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-gitlab': minor +--- + +Implemented discovery for top-level groups defined in config.group or if undefined global top-level group in Gitlab From 05e1bb0e5f869db4afb8cde89dc2b3793ed26aa4 Mon Sep 17 00:00:00 2001 From: Hghtwr Date: Sat, 23 Nov 2024 20:31:53 +0100 Subject: [PATCH 8/8] adopt documentation Signed-off-by: Hghtwr --- docs/integrations/gitlab/org.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/integrations/gitlab/org.md b/docs/integrations/gitlab/org.md index 66ce117aa0..8249a97c24 100644 --- a/docs/integrations/gitlab/org.md +++ b/docs/integrations/gitlab/org.md @@ -170,7 +170,7 @@ catalog: yourProviderId: host: gitlab.com orgEnabled: true - group: org/teams # Required for gitlab.com when `orgEnabled: true`. Optional for self managed. Must not end with slash. Accepts only groups under the provided path (which will be stripped) + group: org/teams # Required for gitlab.com when `orgEnabled: true`. Optional for self managed. Must not end with slash. Accepts only this group and groups under the provided path (which will be stripped) relations: # Optional - INHERITED # Optional. Members of any ancestor groups will also be considered members of the current group. - DESCENDANTS # Optional. Members of any descendant groups will also be considered members of the current group. @@ -240,7 +240,7 @@ catalog: yourProviderId: host: gitlab.com ## Could also be self hosted. orgEnabled: true - group: org/teams # Required for gitlab.com when `orgEnabled: true`. Optional for self managed. Must not end with slash. Accepts only groups under the provided path (which will be stripped) + group: org/teams # Required for gitlab.com when `orgEnabled: true`. Optional for self managed. Must not end with slash. Accepts only this group and groups under the provided path (which will be stripped) restrictUsersToGroup: true # Optional: Backstage will ingest only users directly assigned to org/teams. includeUsersWithoutSeat: false # Optional: Set to true to include users without paid seat, only applicable for SaaS ```