Sync schedules when policy changes
What does this MR do and why?
Sync SEP schedules when policy is linked or unlinked
References
- Persist per-project schedules for scan executio... (!227096 - merged)
- Add per-project scheduling for scan execution p... (!227101 - merged)
-
👉 Sync schedules when policy changes (!227102 - merged)
Database
The table security_scan_execution_project_schedules is new and doesn't contain data in production. The plans provided are generated locally.
OrchestrationPolicyRuleSchedule scopes
.for_security_policy
SELECT "security_orchestration_policy_rule_schedules".*
FROM "security_orchestration_policy_rule_schedules"
WHERE "security_orchestration_policy_rule_schedules"."security_orchestration_policy_configuration_id" = 309
AND "security_orchestration_policy_rule_schedules"."policy_index" = 0
AND "security_orchestration_policy_rule_schedules"."policy_type" = 0
Seq Scan on security_orchestration_policy_rule_schedules (cost=0.00..1.05 rows=1 width=84) (actual time=0.004..0.005 rows=1 loops=1)
Filter: ((security_orchestration_policy_configuration_id = 309) AND (policy_index = 0) AND (policy_type = 0))
Rows Removed by Filter: 2
Planning Time: 0.706 ms
Execution Time: 0.009 ms
ScanExecutionProjectSchedule scopes
.for_project
SELECT "security_scan_execution_project_schedules".*
FROM "security_scan_execution_project_schedules"
WHERE "security_scan_execution_project_schedules"."project_id" = 53
Index Scan using index_security_scan_execution_project_schedules_on_project_id on security_scan_execution_project_schedules (cost=0.15..5.24 rows=5 width=60) (actual time=0.034..0.037 rows=1 loops=1)
Index Cond: (project_id = 53)
Planning Time: 0.604 ms
Execution Time: 0.041 ms
.for_security_policy
SELECT "security_scan_execution_project_schedules".*
FROM "security_scan_execution_project_schedules"
WHERE "security_scan_execution_project_schedules"."security_policy_id" = 826
Index Scan using idx_security_sep_schedules_on_security_policy_id_and_project_id on security_scan_execution_project_schedules (cost=0.15..5.24 rows=5 width=60) (actual time=0.029..0.033 rows=3 loops=1)
Index Cond: (security_policy_id = 826)
Planning Time: 0.033 ms
Execution Time: 0.038 ms
.for_rule_schedules + .for_project
SELECT "security_scan_execution_project_schedules".*
FROM "security_scan_execution_project_schedules"
WHERE "security_scan_execution_project_schedules"."policy_rule_schedule_id" IN (258, 274)
AND "security_scan_execution_project_schedules"."project_id" = 53
Index Scan using idx_security_sep_schedules_on_rule_schedule_id_and_project_id on security_scan_execution_project_schedules (cost=0.15..3.33 rows=1 width=60) (actual time=0.002..0.003 rows=1 loops=1)
Index Cond: ((policy_rule_schedule_id = ANY ('{258,274}'::bigint[])) AND (project_id = 53))
Planning Time: 0.026 ms
Execution Time: 0.006 ms
.insert_all
INSERT INTO "security_scan_execution_project_schedules" ("policy_rule_schedule_id","project_id","security_policy_id","next_run_at","next_run_applied_delay","created_at","updated_at") VALUES (3601626, 77007925, 2341200, '2026-03-27 08:01:04', 27964, '2026-03-26 16:24:29.521410', '2026-03-26 16:24:29.521410'), (3601626, 77007925, 2341200, '2026-03-26 23:27:32', 752, '2026-03-26 16:24:29.521410', '2026-03-26 16:24:29.521410') ON CONFLICT ("policy_rule_schedule_id","project_id") DO NOTHING RETURNING "id";
ModifyTable on public.security_scan_execution_project_schedules (cost=0.00..0.03 rows=2 width=60) (actual time=0.202..0.213 rows=1 loops=1)
Buffers: shared hit=39
WAL: records=7 fpi=0 bytes=507
-> Values Scan on "*VALUES*" (cost=0.00..0.03 rows=2 width=60) (actual time=0.067..0.070 rows=2 loops=1)
Buffers: shared hit=16
Trigger RI_ConstraintTrigger_c_2281413109 for constraint fk_rails_644bb1c41b: time=1.039 calls=1
Trigger RI_ConstraintTrigger_c_2281413117 for constraint fk_rails_11f0ed9e9a: time=111.405 calls=1
Trigger RI_ConstraintTrigger_c_2281413124 for constraint fk_rails_8136c951a3: time=0.733 calls=1
Settings: random_page_cost = '1.5', work_mem = '230MB', seq_page_cost = '4', effective_cache_size = '472585MB', jit = 'off'
Time: 113.673 ms
- planning: 0.236 ms
- execution: 113.437 ms
- I/O read: N/A
- I/O write: N/A
Shared buffers:
- hits: 39 (~312.00 KiB) from the buffer pool
- reads: 0 from the OS file cache, including disk I/O
- dirtied: 0
- writes: 0
https://console.postgres.ai/gitlab/gitlab-production-main/sessions/50225/commands/149094
How to set up and validate locally
- Enable the feature flag
can_execution_policy_project_schedule_creation - Create a project
- In the project, create a scheduled scan execution policy
- In the rails console, verify that a
Security::ScanExecutionProjectSchedulerecord is created - Update the policy name
- In the rails console, verify that the
Security::ScanExecutionProjectSchedulerecord is re-created
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
Related to #592731 (closed)
Edited by Martin Cavoj