diff --git a/config/feature_flags/ops/override_bulk_import_disabled.yml b/config/feature_flags/ops/override_bulk_import_disabled.yml new file mode 100644 index 0000000000000000000000000000000000000000..057170a30ad8a77ae42df9fc1a99f3b940daf2d5 --- /dev/null +++ b/config/feature_flags/ops/override_bulk_import_disabled.yml @@ -0,0 +1,8 @@ +--- +name: override_bulk_import_disabled +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/132431 +rollout_issue_url: +milestone: '16.5' +type: ops +group: group::import and integrate +default_enabled: false diff --git a/lib/api/bulk_imports.rb b/lib/api/bulk_imports.rb index b4ace6cd6bcd273cda0f3918f5e99fe7682bf5b6..9bcc16cf211dd77da0cc2f8b0818da242e585eef 100644 --- a/lib/api/bulk_imports.rb +++ b/lib/api/bulk_imports.rb @@ -33,7 +33,8 @@ def bulk_import_entity end before do - not_found! unless Gitlab::CurrentSettings.bulk_import_enabled? + not_found! unless Gitlab::CurrentSettings.bulk_import_enabled? || + Feature.enabled?(:override_bulk_import_disabled, current_user, type: :ops) authenticate! end diff --git a/lib/api/group_export.rb b/lib/api/group_export.rb index 4cac707ff661cc263fce09d9027e7cd07a883d49..819cc4652f6c1bd037e719a42859dbeb4838adac 100644 --- a/lib/api/group_export.rb +++ b/lib/api/group_export.rb @@ -66,7 +66,8 @@ class GroupExport < ::API::Base resource do before do - not_found! unless Gitlab::CurrentSettings.bulk_import_enabled? + not_found! unless Gitlab::CurrentSettings.bulk_import_enabled? || + Feature.enabled?(:override_bulk_import_disabled, current_user, type: :ops) end desc 'Start relations export' do diff --git a/lib/api/project_export.rb b/lib/api/project_export.rb index 7467b8e564e1fe5f1d8ae99dd4bfde10322cb943..25848d91550bedc26194d5e5e0646edd354c51e9 100644 --- a/lib/api/project_export.rb +++ b/lib/api/project_export.rb @@ -110,7 +110,8 @@ class ProjectExport < ::API::Base resource do before do - not_found! unless Gitlab::CurrentSettings.bulk_import_enabled? + not_found! unless Gitlab::CurrentSettings.bulk_import_enabled? || + Feature.enabled?(:override_bulk_import_disabled, current_user, type: :ops) authorize_admin_project end diff --git a/spec/requests/api/bulk_imports_spec.rb b/spec/requests/api/bulk_imports_spec.rb index d9eed0737b2617f7abe720bda5b464a414f58927..d3d4a723616452f19fa2adb995542f83d37be16e 100644 --- a/spec/requests/api/bulk_imports_spec.rb +++ b/spec/requests/api/bulk_imports_spec.rb @@ -18,8 +18,26 @@ end shared_examples 'disabled feature' do - it 'returns 404' do + before do stub_application_setting(bulk_import_enabled: false) + stub_feature_flags(override_bulk_import_disabled: false) + end + + it_behaves_like '404 response' do + let(:message) { '404 Not Found' } + end + + it 'enables the feature when override flag is enabled for the user' do + stub_feature_flags(override_bulk_import_disabled: user) + + request + + expect(response).not_to have_gitlab_http_status(:not_found) + end + + it 'does not enable the feature when override flag is enabled for another user' do + other_user = create(:user) + stub_feature_flags(override_bulk_import_disabled: other_user) request @@ -71,7 +89,7 @@ end end - include_examples 'disabled feature' + it_behaves_like 'disabled feature' end describe 'POST /bulk_imports' do @@ -328,7 +346,7 @@ end end - include_examples 'disabled feature' + it_behaves_like 'disabled feature' context 'when request exceeds rate limits' do it 'prevents user from starting a new migration' do @@ -352,7 +370,7 @@ expect(json_response.pluck('id')).to contain_exactly(entity_1.id, entity_2.id, entity_3.id) end - include_examples 'disabled feature' + it_behaves_like 'disabled feature' end describe 'GET /bulk_imports/:id' do @@ -365,7 +383,7 @@ expect(json_response['id']).to eq(import_1.id) end - include_examples 'disabled feature' + it_behaves_like 'disabled feature' end describe 'GET /bulk_imports/:id/entities' do @@ -379,7 +397,7 @@ expect(json_response.first['failures'].first['exception_class']).to eq(failure_3.exception_class) end - include_examples 'disabled feature' + it_behaves_like 'disabled feature' end describe 'GET /bulk_imports/:id/entities/:entity_id' do @@ -392,7 +410,7 @@ expect(json_response['id']).to eq(entity_2.id) end - include_examples 'disabled feature' + it_behaves_like 'disabled feature' end context 'when user is unauthenticated' do diff --git a/spec/requests/api/group_export_spec.rb b/spec/requests/api/group_export_spec.rb index ddee2081bcf42c29300fa5c864d1dfd37ef1e76c..d0f7c000544af0fd40c7673c2416fd6e11b3f91b 100644 --- a/spec/requests/api/group_export_spec.rb +++ b/spec/requests/api/group_export_spec.rb @@ -325,13 +325,32 @@ end context 'when bulk import is disabled' do + subject(:request) { post api(path, user) } + before do stub_application_setting(bulk_import_enabled: false) + stub_feature_flags(override_bulk_import_disabled: false) end it_behaves_like '404 response' do let(:message) { '404 Not Found' } - let(:request) { post api(path, user) } + end + + it 'enables the feature when override flag is enabled for the user' do + stub_feature_flags(override_bulk_import_disabled: user) + + request + + expect(response).to have_gitlab_http_status(:accepted) + end + + it 'does not enable the feature when override flag is enabled for another user' do + other_user = create(:user) + stub_feature_flags(override_bulk_import_disabled: other_user) + + request + + expect(response).to have_gitlab_http_status(:not_found) end end end diff --git a/spec/requests/api/project_export_spec.rb b/spec/requests/api/project_export_spec.rb index 8a47eb2dae1974c866c85df5d309ab3357e6b3f8..22729e068da954e3c278a697292481ca99ba876c 100644 --- a/spec/requests/api/project_export_spec.rb +++ b/spec/requests/api/project_export_spec.rb @@ -704,37 +704,63 @@ context 'with bulk_import is disabled' do before do stub_application_setting(bulk_import_enabled: false) + stub_feature_flags(override_bulk_import_disabled: false) + end + + shared_examples 'flag override' do |expected_http_status:| + it 'enables the feature when override flag is enabled for the user' do + stub_feature_flags(override_bulk_import_disabled: user) + + request + + expect(response).to have_gitlab_http_status(expected_http_status) + end + + it 'does not enable the feature when override flag is enabled for another user' do + other_user = create(:user) + stub_feature_flags(override_bulk_import_disabled: other_user) + + request + + expect(response).to have_gitlab_http_status(:not_found) + end end describe 'POST /projects/:id/export_relations' do + subject(:request) { post api(path, user) } + it_behaves_like '404 response' do let(:message) { '404 Not Found' } - - subject(:request) { post api(path, user) } end + + it_behaves_like 'flag override', expected_http_status: :accepted end describe 'GET /projects/:id/export_relations/download' do let_it_be(:export) { create(:bulk_import_export, project: project, relation: 'labels') } let_it_be(:upload) { create(:bulk_import_export_upload, export: export) } + subject(:request) { get api(download_path, user) } + before do upload.update!(export_file: fixture_file_upload('spec/fixtures/bulk_imports/gz/labels.ndjson.gz')) end it_behaves_like '404 response' do let(:message) { '404 Not Found' } - - subject(:request) { get api(download_path, user) } end + + it_behaves_like 'flag override', expected_http_status: :ok end describe 'GET /projects/:id/export_relations/status' do + subject(:request) { get api(status_path, user) } + it_behaves_like '404 response' do let(:message) { '404 Not Found' } - - subject(:request) { get api(status_path, user) } end + + it_behaves_like 'flag override', expected_http_status: :ok end end end