Add ComplianceRequirementsControls::UpdateStatusService
What does this MR do and why?
This MR adds a ComplianceRequirementsControls::UpdateStatusService. This service will be used by the REST API to update an external control.
It only allows pass
and fail
status values, and creates a status record if there hasn't already been a status record created.
This will be used by Add a REST controller for external API access.
Database Query Plans
https://console.postgres.ai/gitlab/gitlab-production-main/sessions/36202/commands/111489
There are no records for this table in postgres.ai so I ran this locally:
explain (analyze, buffers) UPDATE "project_control_compliance_statuses" SET "updated_at" = '2025-02-13 21:44:28.842102', "status" = 1 WHERE "project_control_compliance_statuses"."id" =5;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Update on project_control_compliance_statuses (cost=0.15..2.17 rows=0 width=0) (actual time=0.235..0.236 rows=0 loops=1)
Buffers: shared hit=24 dirtied=1
-> Index Scan using project_control_compliance_statuses_pkey on project_control_compliance_statuses (cost=0.15..2.17 rows=1 width=16) (actual time=0.121..0.122 rows=1 loops=1)
Index Cond: (id = 5)
Buffers: shared hit=5 dirtied=1
Planning:
Buffers: shared hit=98
Planning Time: 1.623 ms
Execution Time: 0.256 ms
(9 rows)
Please let me know if there's anything else I can do to make this easier to review.
References
Issue: Add REST API to update status of external requirement controls
This changeset handles the following parts of the above issue:
-
Create service to update external control status
- Only allow statuses [
pass
andfail
] as defined in ENUM (pending
should not be accepted from an external update) - Audit status stored on control
- Only allow statuses [
In order to limit the size of the changes, the API code will come in a followup MR.
MR acceptance checklist
Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
Screenshots or screen recordings
This change introduces no UI changes
How to set up and validate locally
- Go here and requirement that doesn't have a control for a new or existing framework.
- In a rails console, create an external control for that requirement
requirement = ComplianceManagement::ComplianceFramework::ComplianceRequirement.last
control = requirement.compliance_requirements_controls.create!(name: :default_branch_protected, control_type: :external, external_url: "https://www.example.com", secret_token: "tacocat", namespace_id: requirement.namespace_id)
- Check to make sure there are no statuses for your control
control.project_control_compliance_statuses #=> should return []
- Find your project, and run the service:
project = Project.find(THE_ID_OF_THE_PROJECT)
status_value = "fail"
ComplianceManagement::ComplianceFramework::ComplianceRequirementsControls::UpdateStatusService.new(control:, project:, status_value:).execute
control.project_control_compliance_statuses #=> should return a failed status
- Verify that you can update the existing control
status_value = "pass"
ComplianceManagement::ComplianceFramework::ComplianceRequirementsControls::UpdateStatusService.new(control:, project:, status_value:).execute
control.reload.project_control_compliance_statuses #=> should return a pass status
You should also see new AuditEvent records
AuditEvent.last #=> #<AuditEvent:0x0000000154a31560...