diff --git a/.changeset/wild-bulldogs-suffer.md b/.changeset/wild-bulldogs-suffer.md new file mode 100644 index 0000000000..02f50927e9 --- /dev/null +++ b/.changeset/wild-bulldogs-suffer.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-gitlab': patch +--- + +filter gitlab groups by prefix diff --git a/docs/integrations/gitlab/org.md b/docs/integrations/gitlab/org.md index 2ab72b4bd6..7ddc5202b5 100644 --- a/docs/integrations/gitlab/org.md +++ b/docs/integrations/gitlab/org.md @@ -31,4 +31,10 @@ catalog: yourProviderId: host: gitlab.com orgEnabled: true + group: org/teams # Optional. Must not end with slash. Accepts only groups under the provided path (which will be stripped) + groupPattern: '[\s\S]*' # Optional. Filters found groups based on provided pattern. Defaults to `[\s\S]*`, which means to not filter anything ``` + +When the `group` parameter is provided, the corresponding path prefix will be stripped out from each matching group +when computing the unique entity name. e.g. If `group` is `org/teams`, the name for `org/teams/avengers/gotg` will +be `avengers-gotg`. 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 74649f41da..cff215acd3 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.test.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.test.ts @@ -184,7 +184,6 @@ describe('GitlabOrgDiscoveryEntityProvider', () => { gitlab: { 'test-id': { host: 'test-gitlab', - group: 'test-group', orgEnabled: true, }, }, @@ -350,9 +349,10 @@ describe('GitlabOrgDiscoveryEntityProvider', () => { kind: 'User', metadata: { annotations: { - 'backstage.io/managed-by-location': 'url:test-gitlab/test1', + 'backstage.io/managed-by-location': + 'url:https://test-gitlab/test1', 'backstage.io/managed-by-origin-location': - 'url:test-gitlab/test1', + 'url:https://test-gitlab/test1', 'test-gitlab/user-login': 'https://gitlab.example/test1', }, name: 'test1', @@ -375,9 +375,9 @@ describe('GitlabOrgDiscoveryEntityProvider', () => { metadata: { annotations: { 'backstage.io/managed-by-location': - 'url:test-gitlab/teams/group1-group2', + 'url:https://test-gitlab/group1/group2', 'backstage.io/managed-by-origin-location': - 'url:test-gitlab/teams/group1-group2', + 'url:https://test-gitlab/group1/group2', 'test-gitlab/team-path': 'group1/group2', }, description: 'Group2', diff --git a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts index ad9d9dae79..db1efac86d 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/GitlabOrgDiscoveryEntityProvider.ts @@ -202,6 +202,13 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { continue; } + if ( + this.config.group && + !group.full_path.startsWith(`${this.config.group}/`) + ) { + continue; + } + groupRes.scanned++; groupRes.matches.push(group); @@ -256,7 +263,11 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { type: 'full', entities: [...userEntities, ...groupEntities].map(entity => ({ locationKey: this.getProviderName(), - entity: this.withLocations(this.integration.config.host, entity), + entity: this.withLocations( + this.integration.config.host, + this.integration.config.baseUrl, + entity, + ), })), }); } @@ -276,7 +287,9 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { const entity = this.createGroupEntity(group, host); if (group.parent_id && idMapped.hasOwnProperty(group.parent_id)) { - entity.spec.parent = idMapped[group.parent_id].full_path; + entity.spec.parent = this.groupName( + idMapped[group.parent_id].full_path, + ); } entities.push(entity); @@ -285,11 +298,11 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { return entities; } - private withLocations(host: string, entity: Entity): Entity { + private withLocations(host: string, baseUrl: string, entity: Entity): Entity { const location = entity.kind === 'Group' - ? `url:${host}/teams/${entity.metadata.name}` - : `url:${host}/${entity.metadata.name}`; + ? `url:${baseUrl}/${entity.metadata.annotations?.[`${host}/team-path`]}` + : `url:${baseUrl}/${entity.metadata.name}`; return merge( { metadata: { @@ -341,13 +354,22 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { if (!entity.spec.memberOf) { entity.spec.memberOf = []; } - entity.spec.memberOf.push(group.full_path.replace('/', '-')); + entity.spec.memberOf.push(this.groupName(group.full_path)); } } return entity; } + private groupName(full_path: string): string { + if (this.config.group && full_path.startsWith(`${this.config.group}/`)) { + return full_path + .replace(`${this.config.group}/`, '') + .replaceAll('/', '-'); + } + return full_path.replaceAll('/', '-'); + } + private createGroupEntity(group: GitLabGroup, host: string): GroupEntity { const annotations: { [annotationName: string]: string } = {}; @@ -357,7 +379,7 @@ export class GitlabOrgDiscoveryEntityProvider implements EntityProvider { apiVersion: 'backstage.io/v1alpha1', kind: 'Group', metadata: { - name: group.full_path.replace('/', '-'), + name: this.groupName(group.full_path), annotations: annotations, }, spec: {