diff --git a/db/post_migrate/20241212144443_add_remove_dormant_members_idx_namespace_settings.rb b/db/post_migrate/20241212144443_add_remove_dormant_members_idx_namespace_settings.rb new file mode 100644 index 0000000000000000000000000000000000000000..c227b1a951d7ecd195d390464272afbcaa03d111 --- /dev/null +++ b/db/post_migrate/20241212144443_add_remove_dormant_members_idx_namespace_settings.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +class AddRemoveDormantMembersIdxNamespaceSettings < Gitlab::Database::Migration[2.2] + disable_ddl_transaction! + milestone '17.8' + + COLUMNS = %i[last_dormant_member_review_at remove_dormant_members] + INDEX_NAME = 'idx_namespace_settings_on_remove_dormant_members_review_at' + TABLE = :namespace_settings + + def up + add_concurrent_index( + TABLE, + COLUMNS, + where: 'remove_dormant_members IS true', + name: INDEX_NAME + ) + end + + def down + remove_concurrent_index( + TABLE, + COLUMNS, + name: INDEX_NAME + ) + end +end diff --git a/db/post_migrate/20241212144777_remove_last_dormant_member_review_at_idx_namespace_settings.rb b/db/post_migrate/20241212144777_remove_last_dormant_member_review_at_idx_namespace_settings.rb new file mode 100644 index 0000000000000000000000000000000000000000..0c4bc493313301502320e03999ba725c9bee9741 --- /dev/null +++ b/db/post_migrate/20241212144777_remove_last_dormant_member_review_at_idx_namespace_settings.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class RemoveLastDormantMemberReviewAtIdxNamespaceSettings < Gitlab::Database::Migration[2.2] + disable_ddl_transaction! + + milestone '17.8' + + INDEX_NAME = 'idx_namespace_settings_on_last_dormant_member_review_at' + + def up + remove_concurrent_index :namespace_settings, :last_dormant_member_review_at, name: INDEX_NAME + end + + def down + add_concurrent_index( + :namespace_settings, :last_dormant_member_review_at, + where: 'remove_dormant_members IS true', + name: INDEX_NAME + ) + end +end diff --git a/db/schema_migrations/20241212144443 b/db/schema_migrations/20241212144443 new file mode 100644 index 0000000000000000000000000000000000000000..73dfb61e008ca19cf22839f6145593a8d7972623 --- /dev/null +++ b/db/schema_migrations/20241212144443 @@ -0,0 +1 @@ +3762bf062f641523600b9899d2b77f51cc381df06e283492b8d3de0647b5fe11 \ No newline at end of file diff --git a/db/schema_migrations/20241212144777 b/db/schema_migrations/20241212144777 new file mode 100644 index 0000000000000000000000000000000000000000..e2b307fe03ff400b4fa3b515e7c5ab87170ac27a --- /dev/null +++ b/db/schema_migrations/20241212144777 @@ -0,0 +1 @@ +521f5a1d38e9313554d8b054cb1539a8f5e5dd1713df7715d82ed92dd29938cc \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 9b6e01209fbc5a48033977846b2df1ad1bdb4601..c5859623774127b4e4e7878e6a3848e065caf654 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -29039,7 +29039,7 @@ CREATE INDEX idx_namespace_hostname_import_type_id_source_name_and_username ON i CREATE UNIQUE INDEX idx_namespace_settings_on_default_compliance_framework_id ON namespace_settings USING btree (default_compliance_framework_id); -CREATE INDEX idx_namespace_settings_on_last_dormant_member_review_at ON namespace_settings USING btree (last_dormant_member_review_at) WHERE (remove_dormant_members IS TRUE); +CREATE INDEX idx_namespace_settings_on_remove_dormant_members_review_at ON namespace_settings USING btree (last_dormant_member_review_at, remove_dormant_members) WHERE (remove_dormant_members IS TRUE); CREATE UNIQUE INDEX idx_o11y_log_issue_conn_on_issue_id_logs_search_metadata ON observability_logs_issues_connections USING btree (issue_id, service_name, severity_number, log_timestamp, log_fingerprint, trace_identifier); diff --git a/ee/app/models/ee/namespace_setting.rb b/ee/app/models/ee/namespace_setting.rb index 39b5f390978384ab57bca999542e557bb1119496..cb4ee5f7339dc1dab2748def1c09e68d2252c18f 100644 --- a/ee/app/models/ee/namespace_setting.rb +++ b/ee/app/models/ee/namespace_setting.rb @@ -6,8 +6,17 @@ module NamespaceSetting extend ::Gitlab::Utils::Override prepended do + DORMANT_REVIEW_PERIOD = 18.hours.ago + cascading_attr :duo_features_enabled + scope :requiring_dormant_member_review, ->(limit) do + # look for settings that have not been reviewed in more than + # 18 hours (catering for 6-hourly review schedule) + where(remove_dormant_members: true) + .where('last_dormant_member_review_at < ? OR last_dormant_member_review_at IS NULL', DORMANT_REVIEW_PERIOD) + .limit(limit) + end scope :duo_features_set, ->(setting) { where(duo_features_enabled: setting) } belongs_to :default_compliance_framework, optional: true, class_name: "ComplianceManagement::Framework" diff --git a/ee/spec/models/namespace_setting_spec.rb b/ee/spec/models/namespace_setting_spec.rb index 5512e9371233ef31f17dc2ffd76e665c1711654a..445e1ce5eca66c300d05feb5b59c25141379c82a 100644 --- a/ee/spec/models/namespace_setting_spec.rb +++ b/ee/spec/models/namespace_setting_spec.rb @@ -16,6 +16,20 @@ end end + describe 'scopes' do + describe '.requiring_dormant_member_review', :freeze_time do + it 'returns settings with feature enabled requiring review' do + setting_never_reviewed = create(:namespace_settings, remove_dormant_members: true, last_dormant_member_review_at: nil) + setting_reviewed_19_hours_ago = create(:namespace_settings, remove_dormant_members: true, last_dormant_member_review_at: 19.hours.ago) + create(:namespace_settings, last_dormant_member_review_at: 18.hours.ago) # exactly 18 hours ago + create(:namespace_settings, remove_dormant_members: false) # feature is disabled + + expect(described_class.requiring_dormant_member_review(3)) + .to contain_exactly(setting_never_reviewed, setting_reviewed_19_hours_ago) + end + end + end + describe 'validations' do subject(:settings) { group.namespace_settings }