본문 바로가기
WIKI 기술 지식 베이스

GitLab 조직 데이터

원문 보기 위키 갱신

Backstage 카탈로그는 GitLab에서 직접 조직 데이터(사용자와 그룹)를 가져오도록 설정할 수 있어요. 그 결과는 조직 설정을 그대로 반영한 User 및 Group 엔티티의 계층 구조예요.

출처: 문서

본문

Backstage 카탈로그는 GitLab에서 직접 조직 데이터(사용자와 그룹)를 가져오도록 설정할 수 있어요. 그 결과는 조직 설정을 그대로 반영한 User 및 Group 엔티티의 계층 구조예요.

설치

이 제공자는 기본 제공자 중 하나가 아니므로 먼저 Gitlab 제공자 플러그인을 설치해야 해요.

Backstage 루트 디렉터리에서

yarn --cwd packages/backend add @backstage/plugin-catalog-backend-module-gitlab @backstage/plugin-catalog-backend-module-gitlab-org

그런 다음 백엔드 초기화에 다음을 추가하세요.

packages/backend/src/index.ts

// optional if you want HTTP endpoints to receive external events// backend.add(import('@backstage/plugin-events-backend'));// optional if you want to use AWS SQS instead of HTTP endpoints to receive external events// backend.add(import('@backstage/plugin-events-backend-module-aws-sqs'));// optional - event router for gitlab. See.: https://github.com/backstage/backstage/blob/master/plugins/events-backend-module-gitlab/README.md// backend.add(eventsModuleGitlabEventRouter);// optional - token validator for the gitlab topic// backend.add(eventsModuleGitlabWebhook);backend.add(import('@backstage/plugin-catalog-backend-module-gitlab-org'));

이벤트 지원

GitLab Org용 카탈로그 모듈에는 이벤트 지원이 활성화되어 있어요. 이 모듈은 관련 토픽을 구독하며, 이 이벤트들이 EventsService를 통해 게시될 것으로 기대해요.

제공자는 다음 토픽을 구독해요.

  • gitlab.group_create

  • gitlab.group_destroy

  • gitlab.group_rename

  • gitlab.user_create

  • gitlab.user_destroy

  • gitlab.user_add_to_group

  • gitlab.user_remove_from_group

사전 준비

내장 이벤트 지원을 사용하기 위한 사전 준비가 두 가지 있어요.

  • GitLab에서 system hook 만들기

  • @backstage/plugin-events-backend-module-gitlab 설치 및 구성

GitLab에서 system hook 구성하기

system hook 구성 방법은 공식 문서를 참고하세요.

웹훅(들)은 group_create, group_destroy, group_rename, user_create, user_destroy, user_add_to_group, user_remove_from_group 이벤트에 반응하도록 구성해야 해요.

GitLab 이벤트 모듈 설치 및 구성

GitLab Discovery — Install and Configure GitLab Events Module에 설명된 대로 @backstage/plugin-events-backend-module-gitlab을 설치하고 구성하세요. gitlab 이벤트 모듈은 일반 토픽 gitlab에서 받은 이벤트를 이벤트 유형에 따라 더 구체적인 토픽(예: gitlab.user_add_to_group)으로 라우팅해요. 내장 org 이벤트 지원이 기대하는 것이 바로 이런 더 구체적인 이벤트예요.

Backstage에서 이벤트 받기

아래 옵션 중 하나를 사용해 Backstage 인스턴스가 이 이벤트를 받도록 설정하세요.

  • HTTP 엔드포인트를 사용한 이벤트 설정

  • AWS SQS 모듈을 사용한 이벤트 설정

  • Google Pub/Sub 모듈을 사용한 이벤트 설정

  • Kafka 모듈을 사용한 이벤트 설정

구성

엔티티 제공자를 사용하려면 Gitlab 통합이 설정되어 있어야 해요.

integrations:  gitlab:    - host: gitlab.com      token: ${GITLAB_TOKEN}

이것은 GitLab 인스턴스에서 모든 사용자와 그룹을 쿼리해요. 데이터 양에 따라 상당한 시간과 리소스가 걸릴 수 있어요.

사용된 토큰은 read_api 스코프가 있어야 하며, 가져온 사용자와 그룹은 토큰을 프로비저닝한 계정에 보이는 것들이에요.

note

아래와 같이 schedule이 구성에 설정되어 있어야 합니다.

catalog:  providers:    gitlab:      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 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.          - SHARED_FROM_GROUPS # Optional. Members of any invited groups will also be considered members of the current group.        groupPattern: '[\\s\\S]*' # Optional. Filters found groups based on provided pattern. Defaults to `[\\s\\S]*`, which means to not filter anything        schedule: # Same options as in SchedulerServiceTaskScheduleDefinition. Optional for the Legacy Backend System.          # supports cron, ISO duration, "human duration" as used in code          frequency: { minutes: 30 }          # supports ISO duration, "human duration" as used in code          timeout: { minutes: 3 }

그룹

group 매개변수가 제공되면 고유 엔티티 이름을 계산할 때 각 일치하는 그룹에서 해당 경로 접두사가 제거돼요. 예를 들어 group이 org/teams라면 org/teams/avengers/gotg의 이름은 avengers-gotg가 돼요.

gitlab.com의 경우 orgEnabled: true일 때 조직 내의 특정 그룹으로 수집을 제한하려면 group 매개변수가 필요해요. Group 엔티티는 구성된 그룹 또는 그 하위 그룹에 대해서만 수집되며, 구성된 그룹 경로보다 높은 조상 그룹은 수집되지 않아요. 멤버가 있는 그룹만 수집돼요.

하위 그룹 멤버십

GitLab 그룹과 하위 그룹은 프로젝트와 사용자를 구성하기 위한 계층 구조를 제공해요. 부모 그룹의 멤버십은 하위 그룹까지 자동으로 확장되어 모든 수준에서 일관된 권한을 보장해요. 또한 초대된 그룹(invited groups)을 사용해 그룹을 관리할 수 있는데, 한 그룹을 다른 그룹에 추가할 수 있어요. Backstage 사용자가 GitLab과 통합할 때 이 상속 모델과 초대된 그룹의 개념을 이해하는 것은 그룹 및 사용자 엔티티를 정확하게 매핑하고 관리하는 데 중요해요.

GitLabOrgDiscoveryEntityProvider는 GitLab의 멤버십 동작을 다음과 같이 반영해요.

  • 기본적으로 GitLab 그룹의 모든 직접 멤버는 Backstage의 해당 그룹의 멤버이기도 해요.

  • 하위 그룹의 멤버를 부모 그룹의 멤버로 포함하려면 relations 배열에 DESCENDANTS 옵션을 구성하세요.

  • 부모 그룹의 멤버를 하위 그룹의 멤버로 포함하려면 relations 배열에 INHERITED 옵션을 구성하세요. 이 옵션은 직접 멤버가 없는 하위 그룹도 그룹 수집 과정에서 건너뛰지 않고 Backstage에 그룹 엔티티로 추가되는 효과도 있어요.

  • 초대된 그룹의 멤버를 초대한 그룹의 멤버로 포함하려면 relations 배열에 SHARED_FROM_GROUPS 옵션을 구성하세요.

이전 allowInherited는 향후 버전에서 더 이상 사용되지 않을 거예요. 대신 relations 배열에 INHERITED 옵션을 사용하세요.

catalog:  providers:    gitlab:      development:        relations:          - INHERITED          - DESCENDANTS          - SHARED_FROM_GROUPS

자세한 내용은 GitLab Group Member Relation 문서를 참고하세요.

사용자

자체 호스팅의 경우 기본적으로 전체 인스턴스에서 모든 User 엔티티가 수집돼요.

gitlab.com의 경우 구성된 그룹 경로에 대한 최상위 그룹의 직접 또는 상속 멤버십을 가진 사용자에 대한 User 엔티티가 수집돼요.

두 경우(SaaS 및 자체 호스팅) 모두 restrictUsersToGroup: true 구성 키를 설정하면 app-config.yaml에 정의된 그룹에 직접 할당된 사용자로 수집 사용자를 제한할 수 있어요. 기본적으로 가져오고 싶지 않은 큰 사용자 기반이 있을 때 특히 유용해요.

SaaS에서는 유료 시트가 없는 사용자를 수집에 포함하도록 선택할 수 있어요. Gitlab의 무료 버전을 사용하거나 Gitlab Ultimate에서 Guest Users를 사용할 때 유용할 수 있어요. 안타깝게도 이렇게 하면 사용자 기반에 가져와질 수 있는 일부 기술 사용자도 생겨요. 프로젝트 및 그룹 액세스 토큰은 필터링되지만 서비스 계정은 남아 있어요. Billable Users에 대해 자세히 알아보세요.

catalog:  providers:    gitlab:      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 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

제공자에서 User 및 Group 엔티티 수집 제한하기

선택적으로 orgEnabled: true를 사용할 때 다음 rules 구성으로 제공자가 수집하는 엔티티 유형을 User와 Group 엔티티로만 제한할 수 있어요.

catalog:  providers:    gitlab:      yourOrgDataProviderId:        host: gitlab.com        orgEnabled: true        group: org/teams        rules:          - allow: [Group, User]

커스텀 트랜스포머

GitLab API 응답을 Backstage 엔티티로 매핑하는 데 도움이 되는 자체 변환 로직을 주입할 수 있어요. 사용자와 그룹 요청에 대해 이 작업을 수행해 이 엔티티들을 추가 처리하거나 업데이트할 수 있어요.

이를 활성화하려면 GitlabOrgDiscoveryEntityProvider에 함수를 전달해요. UserTransformer, GroupEntitiesTransformer 또는 GroupNameTransformer(또는 모두)를 전달할 수 있어요. 함수는 API에서 반환된 각 항목(사용자 또는 그룹)에 대해 호출돼요.

아래 예시는 groupNameTransformer 옵션을 사용해 Backstage Group Entity의 metadata.name 속성을 변경해요. 보통 GitLab에서 오는 group.full_path 데이터로 채우는 대신 group.id를 사용해요.

import { loggerToWinstonLogger } from '@backstage/backend-common';import {  coreServices,  createBackendModule,} from '@backstage/backend-plugin-api';import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node';import { eventsServiceRef } from '@backstage/plugin-events-node';import {  GitlabOrgDiscoveryEntityProvider,  GroupNameTransformerOptions,} from '@backstage/plugin-catalog-backend-module-gitlab';function customGroupNameTransformer(  options: GroupNameTransformerOptions,): string {  return `${options.group.id}`;}/** * Registers the GitlabDiscoveryEntityProvider with the catalog processing extension point. * * @alpha */export const catalogModuleGitlabOrgDiscoveryEntityProvider =  createBackendModule({    pluginId: 'catalog',    moduleId: 'gitlabOrgDiscoveryEntityProvider',    register(env) {      env.registerInit({        deps: {          config: coreServices.rootConfig,          catalog: catalogProcessingExtensionPoint,          logger: coreServices.logger,          scheduler: coreServices.scheduler,          events: eventsServiceRef,        },        async init({ config, catalog, logger, scheduler, events }) {          const gitlabOrgDiscoveryEntityProvider =            GitlabOrgDiscoveryEntityProvider.fromConfig(config, {              groupNameTransformer: customGroupNameTransformer,              logger: loggerToWinstonLogger(logger),              events,              scheduler,            });          catalog.addEntityProvider(gitlabOrgDiscoveryEntityProvider);        },      });    },  });

문제 해결

주의: 수집되는 그룹 중 어떤 그룹이 빈 그룹(즉 프로젝트가 없는 그룹)이고, 토큰을 프로비저닝한 사용자가 그룹 공유를 통해 더 높은 수준의 그룹과 공유되고 있으며, 카탈로그에 예상만큼의 Group 엔티티가 보이지 않는다면 이 Gitlab 이슈에 부딪혔을 수 있어요.

더 알아보기 (Learn more)