Convert top_level_group_creation_enabled FF into an application_setting
Related to #506673 (closed)
What does this MR do?
Converts the :top_level_group_creation_enabled feature flag into an application_setting.
- Adds group_setting jsonB column
- Adds an object constraint
- Converts the
:top_level_group_creation_enabledfeature flag to an application_setting - Updates the policy condition to rely on the new application_setting
- Removes the
:top_level_group_creation_enabledfeature flag` from the codebase
Why?
Previously, the top_level_group_creation_enabled feature flag was disabled on gitlab.com to limit group creation abuse but enabled by default on self-managed. Due to the reasons mentioned here, feature flags should not be used for long-lived settings.
Database Review
bin/rails db:migrate
hakeem@habdul-razak--20240918-F45T4 gitlab % bin/rails db:migrate
DEPRECATION WARNING: Support for Rails versions < 7.1 is deprecated and will be removed from ViewComponent 4.0.0 (ViewComponent v4 will remove support for Rails versions < 7.1 no earlier than April 1, 2025) (called from <main> at /Users/hakeem/gitlab-development-kit/gitlab/config/environment.rb:7)
main: == [advisory_lock_connection] object_id: 132960, pg_backend_pid: 45348
main: == 20250410032730 AddGroupSettingsToApplicationSettings: migrating ============
main: -- transaction_open?(nil)
main: -> 0.0000s
main: -- add_column(:application_settings, :group_settings, :jsonb, {:default=>{}, :null=>false})
main: -> 0.0033s
main: -- transaction_open?(nil)
main: -> 0.0000s
main: -- transaction_open?(nil)
main: -> 0.0000s
main: -- execute("ALTER TABLE application_settings\nADD CONSTRAINT check_application_settings_group_settings_is_hash\nCHECK ( (jsonb_typeof(group_settings) = 'object') )\nNOT VALID;\n")
main: -> 0.0017s
main: -- execute("SET statement_timeout TO 0")
main: -> 0.0002s
main: -- execute("ALTER TABLE application_settings VALIDATE CONSTRAINT check_application_settings_group_settings_is_hash;")
main: -> 0.0013s
main: -- execute("RESET statement_timeout")
main: -> 0.0002s
main: == 20250410032730 AddGroupSettingsToApplicationSettings: migrated (0.0437s) ===
main: == [advisory_lock_connection] object_id: 132960, pg_backend_pid: 45348
ci: == [advisory_lock_connection] object_id: 133300, pg_backend_pid: 45350
ci: == 20250410032730 AddGroupSettingsToApplicationSettings: migrating ============
ci: -- transaction_open?(nil)
ci: -> 0.0000s
ci: -- add_column(:application_settings, :group_settings, :jsonb, {:default=>{}, :null=>false})
ci: -> 0.0036s
ci: -- transaction_open?(nil)
ci: -> 0.0000s
ci: -- transaction_open?(nil)
ci: -> 0.0000s
ci: -- execute("ALTER TABLE application_settings\nADD CONSTRAINT check_application_settings_group_settings_is_hash\nCHECK ( (jsonb_typeof(group_settings) = 'object') )\nNOT VALID;\n")
ci: -> 0.0022s
ci: -- execute("SET statement_timeout TO 0")
ci: -> 0.0002s
ci: -- execute("ALTER TABLE application_settings VALIDATE CONSTRAINT check_application_settings_group_settings_is_hash;")
ci: -> 0.0011s
ci: -- execute("RESET statement_timeout")
ci: -> 0.0002s
ci: == 20250410032730 AddGroupSettingsToApplicationSettings: migrated (0.0201s) ===
ci: == [advisory_lock_connection] object_id: 133300, pg_backend_pid: 45350
VERSION=20250410032730 bin/rails db:rollback:main && VERSION=20250410032730 bin/rails db:rollback:ci
hakeem@habdul-razak--20240918-F45T4 gitlab % VERSION=20250410032730 bin/rails db:rollback:main && VERSION=20250410032730 bin/rails db:rollback:ci
DEPRECATION WARNING: Support for Rails versions < 7.1 is deprecated and will be removed from ViewComponent 4.0.0 (ViewComponent v4 will remove support for Rails versions < 7.1 no earlier than April 1, 2025) (called from <main> at /Users/hakeem/gitlab-development-kit/gitlab/config/environment.rb:7)
main: == [advisory_lock_connection] object_id: 132640, pg_backend_pid: 42695
main: == 20250410032730 AddGroupSettingsToApplicationSettings: reverting ============
main: -- transaction_open?(nil)
main: -> 0.0000s
main: -- transaction_open?(nil)
main: -> 0.0000s
main: -- execute(" ALTER TABLE application_settings\n DROP CONSTRAINT IF EXISTS check_application_settings_group_settings_is_hash\n")
main: -> 0.0014s
main: -- transaction_open?(nil)
main: -> 0.0000s
main: -- remove_column(:application_settings, :group_settings)
main: -> 0.0017s
main: == 20250410032730 AddGroupSettingsToApplicationSettings: reverted (0.0229s) ===
main: == [advisory_lock_connection] object_id: 132640, pg_backend_pid: 42695
DEPRECATION WARNING: Support for Rails versions < 7.1 is deprecated and will be removed from ViewComponent 4.0.0 (ViewComponent v4 will remove support for Rails versions < 7.1 no earlier than April 1, 2025) (called from <main> at /Users/hakeem/gitlab-development-kit/gitlab/config/environment.rb:7)
ci: == [advisory_lock_connection] object_id: 132640, pg_backend_pid: 42804
ci: == 20250410032730 AddGroupSettingsToApplicationSettings: reverting ============
ci: -- transaction_open?(nil)
ci: -> 0.0000s
ci: -- transaction_open?(nil)
ci: -> 0.0000s
ci: -- execute(" ALTER TABLE application_settings\n DROP CONSTRAINT IF EXISTS check_application_settings_group_settings_is_hash\n")
ci: -> 0.0014s
ci: -- transaction_open?(nil)
ci: -> 0.0000s
ci: -- remove_column(:application_settings, :group_settings)
ci: -> 0.0018s
ci: == 20250410032730 AddGroupSettingsToApplicationSettings: reverted (0.0246s) ===
ci: == [advisory_lock_connection] object_id: 132640, pg_backend_pid: 42804
How to set up and validate locally
- Create a user, impersonate & create a PAT with an API scope
- Open a terminal & make an API request to create a top_level_group
curl -X POST --header "PRIVATE-TOKEN: <token>" "https://gdk.test:3443/api/v4/groups?name=top_level_group1&path=top_level_group1&visibility=public"
- Verify that it successfully creates a top-level-group
- As an admin, disable the new
top_level_group_creation_enabledapplication_setting
curl -X PUT --header "PRIVATE-TOKEN: <token>" "https://gdk.test:3443/api/v4/application/settings?top_level_group_creation_enabled=false"
- Restart GDK
gdk restart
- Make an API request to create another top_level_group
curl -X POST --header "PRIVATE-TOKEN: <token>" "https://gdk.test:3443/api/v4/groups?name=top_level_group2&path=top_level_group2&visibility=public"
- Verify that it returns a
403 => 'Forbidden'HTTP status code
Next Steps
-
Tag an SRE to disable the top_level_group_creation_enabledapplication_setting on Gitlab.com after merging -
Create a feature-flag cleanup issue for :top_level_group_creation_enabled& link to the original issue #506673 (closed)
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.
Edited by Hakeem Abdul-Razak