diff --git a/app/controllers/import/bulk_imports_controller.rb b/app/controllers/import/bulk_imports_controller.rb index 4064ad7183e016f192b21e6cb47a262dc27ca992..d6bfcb35788c77de63aad701e49c673912278ee2 100644 --- a/app/controllers/import/bulk_imports_controller.rb +++ b/app/controllers/import/bulk_imports_controller.rb @@ -158,7 +158,8 @@ def bulk_import_params end def ensure_bulk_import_enabled - render_404 unless Gitlab::CurrentSettings.bulk_import_enabled? + render_404 unless Gitlab::CurrentSettings.bulk_import_enabled? || + Feature.enabled?(:override_bulk_import_disabled, current_user, type: :ops) end def access_token_key diff --git a/app/views/groups/_import_group_from_another_instance_panel.html.haml b/app/views/groups/_import_group_from_another_instance_panel.html.haml index d8c4f887442fcb0843c39ecdb5e480e4e1434efa..9153abb3c3becc85546ef0b743076fbe6bf4a0a2 100644 --- a/app/views/groups/_import_group_from_another_instance_panel.html.haml +++ b/app/views/groups/_import_group_from_another_instance_panel.html.haml @@ -1,4 +1,4 @@ -- bulk_imports_enabled = Gitlab::CurrentSettings.bulk_import_enabled? +- bulk_imports_enabled = Gitlab::CurrentSettings.bulk_import_enabled? || Feature.enabled?(:override_bulk_import_disabled, current_user, type: :ops) .gl-flex.gl-flex-col.gl-gap-5 - if !bulk_imports_enabled 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 2cbadbfa07ee97d3844a1bfb66382a15e6edad1b..a42245bf732a62c84699d0ec2a2dae6ea16ccf5b 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 4e7c8b134dcfe5272064e814f735625533e65b1e..086d712cc18bacd9429e30353f9b0fe525195663 100644 --- a/lib/api/group_export.rb +++ b/lib/api/group_export.rb @@ -70,7 +70,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 c1e73dedfaf8b79ec83171868111b5db12d05936..48ed6457cda0dba4062f1d91ec5945cd7479f63b 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/controllers/import/bulk_imports_controller_spec.rb b/spec/controllers/import/bulk_imports_controller_spec.rb index 2adc081c0a4e1125e572ad711800dbf1c8f69050..cee8996dfe9432501184bc525395b7e25b679af0 100644 --- a/spec/controllers/import/bulk_imports_controller_spec.rb +++ b/spec/controllers/import/bulk_imports_controller_spec.rb @@ -514,6 +514,7 @@ def get_status(params_override = {}, format = :json) context 'when importing groups and projects by direct transfer is disabled' do before do stub_application_setting(bulk_import_enabled: false) + stub_feature_flags(override_bulk_import_disabled: false) allow_next_instance_of(BulkImports::Clients::HTTP) do |instance| allow(instance).to receive(:validate_instance_version!).and_return(true) @@ -538,6 +539,31 @@ def get_status(params_override = {}, format = :json) expect(response).to have_gitlab_http_status(:not_found) end end + + context 'when the override_bulk_import_disabled feature flag is enabled' do + before do + stub_feature_flags(override_bulk_import_disabled: true) + end + + context 'POST configure' do + it 'does not return 404' do + post :configure, params: { + bulk_import_gitlab_access_token: 'token', bulk_import_gitlab_url: 'https://gitlab.example' + } + + expect(response).to have_gitlab_http_status(:found) + expect(response).to redirect_to(status_import_bulk_imports_url) + end + end + + context 'GET status' do + it 'does not return 404' do + get :status + + expect(response).to have_gitlab_http_status(:ok) + end + end + end end end diff --git a/spec/features/groups/import_export/connect_instance_spec.rb b/spec/features/groups/import_export/connect_instance_spec.rb index 6f2db4ab2de226fc5016646df6741ca7f3990b91..ba38cc51893139a8d33182fbf5d7bc6f9270badb 100644 --- a/spec/features/groups/import_export/connect_instance_spec.rb +++ b/spec/features/groups/import_export/connect_instance_spec.rb @@ -80,14 +80,34 @@ context 'when importing groups and projects by direct transfer is disabled' do before do stub_application_setting(bulk_import_enabled: false) + end - open_import_group + context 'when the override_bulk_import_disabled feature flag is disabled' do + before do + stub_feature_flags(override_bulk_import_disabled: false) + + open_import_group + end + + it 'renders fields and button disabled' do + expect(page).to have_field('GitLab source instance base URL', disabled: true) + expect(page).to have_field('Personal access token', disabled: true) + expect(page).to have_button('Connect instance', disabled: true) + end end - it "doesn't render fields and button" do - expect(page).not_to have_field('GitLab source instance base URL') - expect(page).not_to have_field('Personal access token') - expect(page).not_to have_button('Connect instance') + context 'when the override_bulk_import_disabled feature flag is enabled' do + before do + stub_feature_flags(override_bulk_import_disabled: true) + + open_import_group + end + + it 'renders fields and button enabled' do + expect(page).to have_field('GitLab source instance base URL', disabled: false) + expect(page).to have_field('Personal access token', disabled: false) + expect(page).to have_button('Connect instance', disabled: false) + end end end diff --git a/spec/requests/api/bulk_imports_spec.rb b/spec/requests/api/bulk_imports_spec.rb index 974a56a33487ec6f45b4be73f55b37d2d6d89ae7..107620d62f12b20dbb7fe011d32099ccd391d625 100644 --- a/spec/requests/api/bulk_imports_spec.rb +++ b/spec/requests/api/bulk_imports_spec.rb @@ -52,11 +52,29 @@ shared_examples 'disabled feature' 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 + + expect(response).to have_gitlab_http_status(:not_found) + end end describe 'GET /bulk_imports' do diff --git a/spec/requests/api/group_export_spec.rb b/spec/requests/api/group_export_spec.rb index e88516b6546ea86b770dbe0f2c6d5befa9cab160..fd7c74c8193c399361eb50300b2c30fda0afc921 100644 --- a/spec/requests/api/group_export_spec.rb +++ b/spec/requests/api/group_export_spec.rb @@ -423,11 +423,29 @@ 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).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 end diff --git a/spec/requests/api/project_export_spec.rb b/spec/requests/api/project_export_spec.rb index c4abea5da9ffc0431a5248abcec13bad6a62fb00..3f30f4165d3a25cb8b03d84e44348502b1c95a46 100644 --- a/spec/requests/api/project_export_spec.rb +++ b/spec/requests/api/project_export_spec.rb @@ -735,37 +735,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', user: user) } 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