InfoGrab DocsInfoGrab Docs

Secrets Manager 테스트

요약

Secrets Manager 백엔드 스펙은 실제 OpenBao 개발 서버를 대상으로 실행됩니다. OpenBao와 통신하는 스펙에는 :gitlab_secrets_manager RSpec 태그가 있어야 합니다. 이 태그는 각 예제에 대해 다음을 자동으로 수행합니다.

Secrets Manager 백엔드 스펙은 실제 OpenBao 개발 서버를 대상으로 실행됩니다. 프론트엔드 스펙에는 OpenBao가 필요하지 않습니다. 이에 대해서는 Secrets Manager 프론트엔드 개발을 참고합니다.

백엔드 스펙#

OpenBao와 통신하는 스펙에는 :gitlab_secrets_manager RSpec 태그가 있어야 합니다. 이 태그는 ee/spec/spec_helper.rb에 연결되어 있습니다.

이 태그는 각 예제에 대해 다음을 자동으로 수행합니다.

  • native_secrets_management 라이선스 기능을 스텁 처리합니다.
  • ci_jwt_signing_key를 ee/spec/fixtures/secrets_manager/의 테스트 키 쌍으로 스텁 처리합니다.
  • 로컬 OpenBao 개발 서버를 시작합니다.
  • JWT 인증을 구성합니다.
  • 예제가 끝나면 key-value(KV) 시크릿 엔진을 초기화합니다.

태그가 지정된 첫 스펙을 실행하면 OpenBao 테스트 바이너리를 빌드하므로 시간이 걸립니다. 이후 실행에서는 바이너리를 재사용합니다. 예제에서 서버 설정을 제외하려면 :skip_openbao_setup 메타데이터를 사용합니다.

명령 예시:

bundle exec rspec ee/spec/services/secrets_management/
bundle exec rspec ee/spec/requests/api/graphql/secrets_management/

등록(enrollment) 테스트 헬퍼(SecretsManagement::EnrollmentHelpers)는 모든 Enterprise Edition(EE) 스펙에 포함되므로, 등록을 설정하기 위해 :gitlab_secrets_manager 태그가 필요하지는 않습니다.

스펙은 OpenID Connect(OIDC) 디스커버리 대신 하드코딩된 JSON Web Key Set(JWKS)을 사용하므로, 스펙을 실행하는 데 실행 중인 웹 서버가 필요하지 않습니다. 로컬 수동 테스트에는 필요합니다.

스펙 헬퍼 모듈#

이 모듈은 ee/spec/support/helpers/secrets_management/ 아래에 있으며 ee/spec/spec_helper.rb에 연결되어 있습니다.

모듈 포함 대상 제공 항목
SecretsManagement::GitlabSecretsManagerHelpers :gitlab_secrets_manager 태그가 지정된 스펙 프로비저닝, 시크릿의 생성·읽기·업데이트·삭제(CRUD), 권한 업데이트, OpenBao 상태 검증.
SecretsManagement::EnrollmentHelpers 모든 EE 스펙 인스턴스 등록 및 자격 스텁.
SecretsManagement::CapabilityHelpers 모든 EE 스펙 사용자에게 해당 기능이 있을 때만 표시되는 UI 요소가 사용하는 실시간 OpenBao 기능 조회 스텁.

SecretsManagement::GitlabSecretsManagerHelpers는 주요 OpenBao 헬퍼 모듈입니다. 주요 메서드는 다음과 같습니다.

  • provision_project_secrets_manager(secrets_manager, user, auto_enroll: true)와 provision_group_secrets_manager(secrets_manager, user, auto_enroll: true). 테스트 OpenBao 서버에 대해 실제 프로비저닝 서비스를 실행합니다. auto_enroll은 먼저 enroll_instance_in_secrets_manager를 호출합니다.
  • deprovision_project_secrets_manager(secrets_manager, user)와 deprovision_group_secrets_manager(secrets_manager, user). 프로비저닝 해제 유지 관리 작업을 만들고 프로비저닝 해제 서비스를 실행합니다.
  • create_project_secret(user:, project:, name:, branch:, environment:, value:, ...)와 create_group_secret(user:, group:, name:, protected:, environment:, value:, ...). 생성 서비스를 실행하고 결과 시크릿을 반환합니다.
  • update_project_secrets_permission(user:, project:, principal:, actions:, expired_at:)와 update_group_secrets_permission(...). 권한 업데이트 서비스를 실행합니다.
  • expect_kv_secret_to_have_value, expect_kv_secret_to_have_custom_metadata, expect_kv_secret_not_to_exist, expect_jwt_auth_engine_to_be_mounted, expect_jwt_cel_role_to_exist, expect_policy_to_exist, expect_namespace_to_exist와 그 부정형 같은 검증 헬퍼. 각 헬퍼는 확인할 OpenBao 네임스페이스 경로와 마운트 또는 정책 세부 정보를 받습니다.
  • cancel_exclusive_project_secret_operation_lease(project)와 cancel_exclusive_group_secret_operation_lease(group). 예제 사이에 유지된 독점 리스를 해제합니다.
  • secret_rotation_info_for_project_secret(project, name, version)와 secret_rotation_info_for_group_secret(group, name, version). ProjectSecretRotationInfo 또는 GroupSecretRotationInfo 행을 조회합니다.
  • secrets_manager_client. 직접적인 저수준 검증을 위한 루트 수준 OpenBao 클라이언트인 SecretsManagement::TestClient를 반환합니다.

SecretsManagement::EnrollmentHelpers는 다음을 제공합니다.

  • enroll_instance_in_secrets_manager. 인스턴스가 등록된 것으로 스텁 처리하고 stub_secrets_manager_entitlement를 호출합니다.
  • stub_secrets_manager_entitlement(state: :paid, blocked_reason: :grace). 지정한 상태를 반환하도록 SecretsManagement::Entitlement.for를 스텁 처리합니다. 각 상태의 의미는 Secrets Manager 이행 및 자격을 참고합니다.

프로비저닝된 Secrets Manager 레코드용 팩토리#

팩토리 클래스 주요 트레이트
:project_secrets_manager SecretsManagement::ProjectSecretsManager STATUSES의 키마다 트레이트 하나(예: :provisioning, :active, :deprovisioning).
:group_secrets_manager SecretsManagement::GroupSecretsManager 프로젝트 팩토리와 같은 패턴.
:project_secrets_manager_maintenance_task SecretsManagement::ProjectSecretsManagerMaintenanceTask :provision, :deprovision, :processing, :stale.
:group_secrets_manager_maintenance_task SecretsManagement::GroupSecretsManagerMaintenanceTask 프로젝트 유지 관리 작업 팩토리와 같은 트레이트.
:project_secret_rotation_info SecretsManagement::ProjectSecretRotationInfo 없음.
:group_secret_rotation_info SecretsManagement::GroupSecretRotationInfo 없음.
:namespace_secret_count SecretsManagement::NamespaceSecretCount 없음.
:secrets_manager_namespace_enrollment SecretsManagement::NamespaceEnrollment :disabled, :add_on_requested.
:sm_recovery_key SecretsManagement::RecoveryKey 없음.

:active 트레이트로 팩토리 레코드를 만들면 status 칼럼만 설정됩니다. OpenBao에서는 아무것도 프로비저닝하지 않습니다. 스펙에서 완전히 프로비저닝된 Secrets Manager를 얻으려면 레코드를 만든 다음 해당하는 provision_*_secrets_manager 헬퍼를 호출합니다.

let(:secrets_manager) { create(:project_secrets_manager, project: project) }

before do
  provision_project_secrets_manager(secrets_manager, user)
end

공유 예제와 공유 컨텍스트#

모델, 서비스, 워커 스펙은 ee/spec/support/shared_examples/ 아래의 RSpec.shared_examples 블록으로 동작을 재사용합니다. 대부분의 서비스 수준 예제는 resource_type 인수('project' 또는 'group')를 받습니다. 예: it_behaves_like 'a service for creating a secret', 'project'.

범주 디렉터리 예시
모델 shared_examples/models/secrets_management/ 'a secrets manager', 'a secrets manager maintenance task', 'a secret model', 'a secrets permission', 'a secret rotation info'.
프로비저닝 및 프로비저닝 해제 shared_examples/services/secrets_management/ 'a secrets manager initialize service', 'a secrets manager provision service'(및 granting the Maintainer default, not granting 변형), 'a secrets manager deprovision service', 'a secrets manager deprovision worker'.
시크릿 CRUD shared_examples/services/secrets_management/ 'a service for creating a secret', 'a service for updating a secret', 'a service for deleting a secret', 'a service for listing secrets needing rotation', 'a batch reminder service processing secrets'.
권한 shared_examples/services/secrets_management/ 'a service for listing secrets permissions', 'a service for updating secrets permissions', 'a service for deleting secrets permissions'.
자격 및 리스 shared_examples/services/secrets_management/ 'a secrets manager entitlement gate', 'an operation requiring an exclusive project secret operation lease', 'an operation requiring an exclusive group secret operation lease'.
워커 shared_examples/workers/secrets_management/ 'a secrets manager provision worker', 'a secrets manager maintenance tasks cron worker', 'a secrets manager reap orphan tasks cron worker', 'a secret rotation reminder batch worker'.
GraphQL 요청 shared_examples/requests/api/graphql/secrets_management/ 'a GraphQL mutation for updating secrets permissions', 'a GraphQL mutation for deleting secrets permissions', 'a GraphQL query for listing secrets permissions', 'a secrets manager mutation blocked on entitlement', 'a secrets manager delete mutation gated on entitlement', 'a delete that still runs under a read-only entitlement', 'a secrets manager mutation blocked on an inactive namespace'.
GraphQL이 아닌 요청 shared_examples/requests/secrets_management/ 'an API request requiring an exclusive project secret operation lease', 'an API request requiring an exclusive group secret operation lease'.

deprovision_service_examples.rb의 프로비저닝 해제 공유 예제는 이를 포함하는 스펙이 let으로 다음을 정의해야 합니다. secrets_manager, maintenance_task, service, result, payload_key, find_sm_target, parent_fk_column(:project_id 또는 :group_id), 그리고 expect_no_policies_at(full_path) 메서드입니다. 정확한 규약은 파일 헤더 주석을 읽어 확인합니다.

프로젝트와 그룹 표면이 서로 다른 키워드 인수를 받으므로, 레코드별 및 대량 InitiateDeprovisionService 스펙은 공유하지 않습니다. 이 스펙은 ee/spec/services/secrets_management/project_secrets_managers/initiate_deprovision_service_spec.rb와 대응하는 group_secrets_managers/ 스펙에 직접 있습니다.

OpenBao와 통신하는 서비스 스펙의 표준 구조#

RSpec.describe SecretsManagement::ProjectSecrets::CreateService,
  :gitlab_secrets_manager, feature_category: :secrets_management do
  let_it_be_with_reload(:project) { create(:project) }
  let_it_be(:user) { create(:user) }

  let(:secrets_manager) { create(:project_secrets_manager, project: project) }
  let(:service) { described_class.new(project, user) }

  before_all do
    project.add_owner(user)
  end

  it_behaves_like 'a service for creating a secret', 'project'

  describe '#execute', :aggregate_failures, :freeze_time do
    before do
      provision_project_secrets_manager(secrets_manager, user)
    end

    it 'creates a project secret' do
      result = service.execute(name: 'SECRET', value: 'val', environment: '*', branch: '*')
      expect(result).to be_success
    end
  end
end

이러한 스펙의 일반적인 패턴은 다음과 같습니다.

  • OpenBao 측 부수 효과가 예제당 한 번만 실행되도록 Secrets Manager는 let이 아니라 before 블록에서 프로비저닝합니다.

  • 동작이 타임스탬프에 의존할 때(예: 오래된 프로비저닝 임계값) :freeze_time을 사용합니다.

  • 예제가 관련된 검증을 여러 개 수행할 때 :aggregate_failures를 사용합니다.

  • 권한 시나리오는 역할이 있는 사용자를 만들고, 필요하면 성공을 검증하기 전에 update_project_secrets_permission 또는 update_group_secrets_permission으로 명시적 권한을 부여해 테스트합니다.

  • WebMock으로 OpenBao 실패를 시뮬레이션합니다. 예를 들어 부분 쓰기 이후의 타임아웃입니다.

    before do
      webmock_enable!(allow_localhost: false)
      stub_request(:post, secret_create_path).to_timeout
    end
    
    after do
      webmock_enable!(allow_localhost: true)
      WebMock.reset!
    end
    

자격 및 등록 스텁#

스펙에서 SecretsManagement::Entitlement.for가 반환하는 값을 제어하려면 CustomersDot이나 애드온 구매 미러를 직접 스텁 처리하지 않고 SecretsManagement::EnrollmentHelpers의 stub_secrets_manager_entitlement(state:, blocked_reason:)를 사용합니다. 기본 상태(:paid)에서는 구독을 모델링하지 않아도 자격이 필요한 코드가 계속 실행됩니다. 특정 자격 상태를 검증하는 스펙은 테스트 대상 상태로 다시 스텁 처리합니다. 예: state: :blocked, blocked_reason: :grace.

enroll_instance_in_secrets_manager는 인스턴스 수준 등록을 스텁 처리하고 stub_secrets_manager_entitlement를 호출합니다. 가용성 검사에 막히는 코드를 검증하는 스펙에서는 이를 직접 호출합니다. 이를 대신 호출해 주는 provision_project_secrets_manager나 provision_group_secrets_manager를 거치지 않는 경우입니다.

GitLab.com 네임스페이스 등록 분기에서는 인스턴스 등록에 의존하지 않고 Gitlab.com?를 설정하고 :secrets_manager_namespace_enrollment 팩토리 레코드를 만듭니다.

각 자격 상태의 의미는 자격 상태를 참고합니다.

QA 엔드 투 엔드 스펙#

브라우저 UI 엔드 투 엔드 스펙은 qa/qa/specs/features/ee/browser_ui/10_software_supply_chain_security/secrets_management/ 아래에 있습니다. 이 디렉터리는 project_secrets_manager/와 group_secrets_manager/ 디렉터리로 나뉩니다. 각각 CRUD, 액세스 제어, 감사 이벤트 범위를 위한 permissions/와 project_secret/ 또는 group_secret/ 하위 디렉터리가 있습니다.

지원 코드는 다음 위치에 있습니다.

  • qa/qa/ee/page/project/secure/secrets_manager.rb와 qa/qa/ee/page/group/secure/secrets_manager.rb. Secrets Manager UI용 페이지 객체.
  • qa/qa/ee/page/component/secrets_manager_permissions.rb와 secrets_manager_settings.rb. 공유 페이지 컴포넌트.
  • qa/qa/ee/support/helpers/secrets_management/secrets_manager_helper.rb. 엔드 투 엔드 테스트 헬퍼.
  • qa/qa/specs/features/shared_contexts/secrets_management/secret_permission_shared_context.rb와 group_secret_permission_shared_context.rb. 권한 스펙용 공유 컨텍스트.

Kubernetes 클러스터 테스트#

GDK로는 모든 경우를 다룰 수 없습니다. Kubernetes 클러스터 안에서 OpenBao를 실행해야 한다면(예: 이에 대해 External Secrets Operator를 테스트하는 경우), GitLab과 OpenBao를 로컬 클러스터에 배포하는 Caproni를 사용합니다. 지원이 필요하면 #proj_caproni Slack 채널에 문의합니다.

Secrets Manager 테스트

GitLab v19.5
원문 보기

요약

Secrets Manager 백엔드 스펙은 실제 OpenBao 개발 서버를 대상으로 실행됩니다. OpenBao와 통신하는 스펙에는 :gitlab_secrets_manager RSpec 태그가 있어야 합니다. 이 태그는 각 예제에 대해 다음을 자동으로 수행합니다.

Secrets Manager 백엔드 스펙은 실제 OpenBao 개발 서버를 대상으로 실행됩니다. 프론트엔드 스펙에는 OpenBao가 필요하지 않습니다. 이에 대해서는 Secrets Manager 프론트엔드 개발을 참고합니다.

백엔드 스펙#

OpenBao와 통신하는 스펙에는 :gitlab_secrets_manager RSpec 태그가 있어야 합니다. 이 태그는 ee/spec/spec_helper.rb에 연결되어 있습니다.

이 태그는 각 예제에 대해 다음을 자동으로 수행합니다.

  • native_secrets_management 라이선스 기능을 스텁 처리합니다.
  • ci_jwt_signing_key를 ee/spec/fixtures/secrets_manager/의 테스트 키 쌍으로 스텁 처리합니다.
  • 로컬 OpenBao 개발 서버를 시작합니다.
  • JWT 인증을 구성합니다.
  • 예제가 끝나면 key-value(KV) 시크릿 엔진을 초기화합니다.

태그가 지정된 첫 스펙을 실행하면 OpenBao 테스트 바이너리를 빌드하므로 시간이 걸립니다. 이후 실행에서는 바이너리를 재사용합니다. 예제에서 서버 설정을 제외하려면 :skip_openbao_setup 메타데이터를 사용합니다.

명령 예시:

bundle exec rspec ee/spec/services/secrets_management/
bundle exec rspec ee/spec/requests/api/graphql/secrets_management/

등록(enrollment) 테스트 헬퍼(SecretsManagement::EnrollmentHelpers)는 모든 Enterprise Edition(EE) 스펙에 포함되므로, 등록을 설정하기 위해 :gitlab_secrets_manager 태그가 필요하지는 않습니다.

스펙은 OpenID Connect(OIDC) 디스커버리 대신 하드코딩된 JSON Web Key Set(JWKS)을 사용하므로, 스펙을 실행하는 데 실행 중인 웹 서버가 필요하지 않습니다. 로컬 수동 테스트에는 필요합니다.

스펙 헬퍼 모듈#

이 모듈은 ee/spec/support/helpers/secrets_management/ 아래에 있으며 ee/spec/spec_helper.rb에 연결되어 있습니다.

모듈 포함 대상 제공 항목
SecretsManagement::GitlabSecretsManagerHelpers :gitlab_secrets_manager 태그가 지정된 스펙 프로비저닝, 시크릿의 생성·읽기·업데이트·삭제(CRUD), 권한 업데이트, OpenBao 상태 검증.
SecretsManagement::EnrollmentHelpers 모든 EE 스펙 인스턴스 등록 및 자격 스텁.
SecretsManagement::CapabilityHelpers 모든 EE 스펙 사용자에게 해당 기능이 있을 때만 표시되는 UI 요소가 사용하는 실시간 OpenBao 기능 조회 스텁.

SecretsManagement::GitlabSecretsManagerHelpers는 주요 OpenBao 헬퍼 모듈입니다. 주요 메서드는 다음과 같습니다.

  • provision_project_secrets_manager(secrets_manager, user, auto_enroll: true)와 provision_group_secrets_manager(secrets_manager, user, auto_enroll: true). 테스트 OpenBao 서버에 대해 실제 프로비저닝 서비스를 실행합니다. auto_enroll은 먼저 enroll_instance_in_secrets_manager를 호출합니다.
  • deprovision_project_secrets_manager(secrets_manager, user)와 deprovision_group_secrets_manager(secrets_manager, user). 프로비저닝 해제 유지 관리 작업을 만들고 프로비저닝 해제 서비스를 실행합니다.
  • create_project_secret(user:, project:, name:, branch:, environment:, value:, ...)와 create_group_secret(user:, group:, name:, protected:, environment:, value:, ...). 생성 서비스를 실행하고 결과 시크릿을 반환합니다.
  • update_project_secrets_permission(user:, project:, principal:, actions:, expired_at:)와 update_group_secrets_permission(...). 권한 업데이트 서비스를 실행합니다.
  • expect_kv_secret_to_have_value, expect_kv_secret_to_have_custom_metadata, expect_kv_secret_not_to_exist, expect_jwt_auth_engine_to_be_mounted, expect_jwt_cel_role_to_exist, expect_policy_to_exist, expect_namespace_to_exist와 그 부정형 같은 검증 헬퍼. 각 헬퍼는 확인할 OpenBao 네임스페이스 경로와 마운트 또는 정책 세부 정보를 받습니다.
  • cancel_exclusive_project_secret_operation_lease(project)와 cancel_exclusive_group_secret_operation_lease(group). 예제 사이에 유지된 독점 리스를 해제합니다.
  • secret_rotation_info_for_project_secret(project, name, version)와 secret_rotation_info_for_group_secret(group, name, version). ProjectSecretRotationInfo 또는 GroupSecretRotationInfo 행을 조회합니다.
  • secrets_manager_client. 직접적인 저수준 검증을 위한 루트 수준 OpenBao 클라이언트인 SecretsManagement::TestClient를 반환합니다.

SecretsManagement::EnrollmentHelpers는 다음을 제공합니다.

  • enroll_instance_in_secrets_manager. 인스턴스가 등록된 것으로 스텁 처리하고 stub_secrets_manager_entitlement를 호출합니다.
  • stub_secrets_manager_entitlement(state: :paid, blocked_reason: :grace). 지정한 상태를 반환하도록 SecretsManagement::Entitlement.for를 스텁 처리합니다. 각 상태의 의미는 Secrets Manager 이행 및 자격을 참고합니다.

프로비저닝된 Secrets Manager 레코드용 팩토리#

팩토리 클래스 주요 트레이트
:project_secrets_manager SecretsManagement::ProjectSecretsManager STATUSES의 키마다 트레이트 하나(예: :provisioning, :active, :deprovisioning).
:group_secrets_manager SecretsManagement::GroupSecretsManager 프로젝트 팩토리와 같은 패턴.
:project_secrets_manager_maintenance_task SecretsManagement::ProjectSecretsManagerMaintenanceTask :provision, :deprovision, :processing, :stale.
:group_secrets_manager_maintenance_task SecretsManagement::GroupSecretsManagerMaintenanceTask 프로젝트 유지 관리 작업 팩토리와 같은 트레이트.
:project_secret_rotation_info SecretsManagement::ProjectSecretRotationInfo 없음.
:group_secret_rotation_info SecretsManagement::GroupSecretRotationInfo 없음.
:namespace_secret_count SecretsManagement::NamespaceSecretCount 없음.
:secrets_manager_namespace_enrollment SecretsManagement::NamespaceEnrollment :disabled, :add_on_requested.
:sm_recovery_key SecretsManagement::RecoveryKey 없음.

:active 트레이트로 팩토리 레코드를 만들면 status 칼럼만 설정됩니다. OpenBao에서는 아무것도 프로비저닝하지 않습니다. 스펙에서 완전히 프로비저닝된 Secrets Manager를 얻으려면 레코드를 만든 다음 해당하는 provision_*_secrets_manager 헬퍼를 호출합니다.

let(:secrets_manager) { create(:project_secrets_manager, project: project) }

before do
  provision_project_secrets_manager(secrets_manager, user)
end

공유 예제와 공유 컨텍스트#

모델, 서비스, 워커 스펙은 ee/spec/support/shared_examples/ 아래의 RSpec.shared_examples 블록으로 동작을 재사용합니다. 대부분의 서비스 수준 예제는 resource_type 인수('project' 또는 'group')를 받습니다. 예: it_behaves_like 'a service for creating a secret', 'project'.

범주 디렉터리 예시
모델 shared_examples/models/secrets_management/ 'a secrets manager', 'a secrets manager maintenance task', 'a secret model', 'a secrets permission', 'a secret rotation info'.
프로비저닝 및 프로비저닝 해제 shared_examples/services/secrets_management/ 'a secrets manager initialize service', 'a secrets manager provision service'(및 granting the Maintainer default, not granting 변형), 'a secrets manager deprovision service', 'a secrets manager deprovision worker'.
시크릿 CRUD shared_examples/services/secrets_management/ 'a service for creating a secret', 'a service for updating a secret', 'a service for deleting a secret', 'a service for listing secrets needing rotation', 'a batch reminder service processing secrets'.
권한 shared_examples/services/secrets_management/ 'a service for listing secrets permissions', 'a service for updating secrets permissions', 'a service for deleting secrets permissions'.
자격 및 리스 shared_examples/services/secrets_management/ 'a secrets manager entitlement gate', 'an operation requiring an exclusive project secret operation lease', 'an operation requiring an exclusive group secret operation lease'.
워커 shared_examples/workers/secrets_management/ 'a secrets manager provision worker', 'a secrets manager maintenance tasks cron worker', 'a secrets manager reap orphan tasks cron worker', 'a secret rotation reminder batch worker'.
GraphQL 요청 shared_examples/requests/api/graphql/secrets_management/ 'a GraphQL mutation for updating secrets permissions', 'a GraphQL mutation for deleting secrets permissions', 'a GraphQL query for listing secrets permissions', 'a secrets manager mutation blocked on entitlement', 'a secrets manager delete mutation gated on entitlement', 'a delete that still runs under a read-only entitlement', 'a secrets manager mutation blocked on an inactive namespace'.
GraphQL이 아닌 요청 shared_examples/requests/secrets_management/ 'an API request requiring an exclusive project secret operation lease', 'an API request requiring an exclusive group secret operation lease'.

deprovision_service_examples.rb의 프로비저닝 해제 공유 예제는 이를 포함하는 스펙이 let으로 다음을 정의해야 합니다. secrets_manager, maintenance_task, service, result, payload_key, find_sm_target, parent_fk_column(:project_id 또는 :group_id), 그리고 expect_no_policies_at(full_path) 메서드입니다. 정확한 규약은 파일 헤더 주석을 읽어 확인합니다.

프로젝트와 그룹 표면이 서로 다른 키워드 인수를 받으므로, 레코드별 및 대량 InitiateDeprovisionService 스펙은 공유하지 않습니다. 이 스펙은 ee/spec/services/secrets_management/project_secrets_managers/initiate_deprovision_service_spec.rb와 대응하는 group_secrets_managers/ 스펙에 직접 있습니다.

OpenBao와 통신하는 서비스 스펙의 표준 구조#

RSpec.describe SecretsManagement::ProjectSecrets::CreateService,
  :gitlab_secrets_manager, feature_category: :secrets_management do
  let_it_be_with_reload(:project) { create(:project) }
  let_it_be(:user) { create(:user) }

  let(:secrets_manager) { create(:project_secrets_manager, project: project) }
  let(:service) { described_class.new(project, user) }

  before_all do
    project.add_owner(user)
  end

  it_behaves_like 'a service for creating a secret', 'project'

  describe '#execute', :aggregate_failures, :freeze_time do
    before do
      provision_project_secrets_manager(secrets_manager, user)
    end

    it 'creates a project secret' do
      result = service.execute(name: 'SECRET', value: 'val', environment: '*', branch: '*')
      expect(result).to be_success
    end
  end
end

이러한 스펙의 일반적인 패턴은 다음과 같습니다.

  • OpenBao 측 부수 효과가 예제당 한 번만 실행되도록 Secrets Manager는 let이 아니라 before 블록에서 프로비저닝합니다.

  • 동작이 타임스탬프에 의존할 때(예: 오래된 프로비저닝 임계값) :freeze_time을 사용합니다.

  • 예제가 관련된 검증을 여러 개 수행할 때 :aggregate_failures를 사용합니다.

  • 권한 시나리오는 역할이 있는 사용자를 만들고, 필요하면 성공을 검증하기 전에 update_project_secrets_permission 또는 update_group_secrets_permission으로 명시적 권한을 부여해 테스트합니다.

  • WebMock으로 OpenBao 실패를 시뮬레이션합니다. 예를 들어 부분 쓰기 이후의 타임아웃입니다.

    before do
      webmock_enable!(allow_localhost: false)
      stub_request(:post, secret_create_path).to_timeout
    end
    
    after do
      webmock_enable!(allow_localhost: true)
      WebMock.reset!
    end
    

자격 및 등록 스텁#

스펙에서 SecretsManagement::Entitlement.for가 반환하는 값을 제어하려면 CustomersDot이나 애드온 구매 미러를 직접 스텁 처리하지 않고 SecretsManagement::EnrollmentHelpers의 stub_secrets_manager_entitlement(state:, blocked_reason:)를 사용합니다. 기본 상태(:paid)에서는 구독을 모델링하지 않아도 자격이 필요한 코드가 계속 실행됩니다. 특정 자격 상태를 검증하는 스펙은 테스트 대상 상태로 다시 스텁 처리합니다. 예: state: :blocked, blocked_reason: :grace.

enroll_instance_in_secrets_manager는 인스턴스 수준 등록을 스텁 처리하고 stub_secrets_manager_entitlement를 호출합니다. 가용성 검사에 막히는 코드를 검증하는 스펙에서는 이를 직접 호출합니다. 이를 대신 호출해 주는 provision_project_secrets_manager나 provision_group_secrets_manager를 거치지 않는 경우입니다.

GitLab.com 네임스페이스 등록 분기에서는 인스턴스 등록에 의존하지 않고 Gitlab.com?를 설정하고 :secrets_manager_namespace_enrollment 팩토리 레코드를 만듭니다.

각 자격 상태의 의미는 자격 상태를 참고합니다.

QA 엔드 투 엔드 스펙#

브라우저 UI 엔드 투 엔드 스펙은 qa/qa/specs/features/ee/browser_ui/10_software_supply_chain_security/secrets_management/ 아래에 있습니다. 이 디렉터리는 project_secrets_manager/와 group_secrets_manager/ 디렉터리로 나뉩니다. 각각 CRUD, 액세스 제어, 감사 이벤트 범위를 위한 permissions/와 project_secret/ 또는 group_secret/ 하위 디렉터리가 있습니다.

지원 코드는 다음 위치에 있습니다.

  • qa/qa/ee/page/project/secure/secrets_manager.rb와 qa/qa/ee/page/group/secure/secrets_manager.rb. Secrets Manager UI용 페이지 객체.
  • qa/qa/ee/page/component/secrets_manager_permissions.rb와 secrets_manager_settings.rb. 공유 페이지 컴포넌트.
  • qa/qa/ee/support/helpers/secrets_management/secrets_manager_helper.rb. 엔드 투 엔드 테스트 헬퍼.
  • qa/qa/specs/features/shared_contexts/secrets_management/secret_permission_shared_context.rb와 group_secret_permission_shared_context.rb. 권한 스펙용 공유 컨텍스트.

Kubernetes 클러스터 테스트#

GDK로는 모든 경우를 다룰 수 없습니다. Kubernetes 클러스터 안에서 OpenBao를 실행해야 한다면(예: 이에 대해 External Secrets Operator를 테스트하는 경우), GitLab과 OpenBao를 로컬 클러스터에 배포하는 Caproni를 사용합니다. 지원이 필요하면 #proj_caproni Slack 채널에 문의합니다.