summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/contextual_sidebar.js17
-rw-r--r--app/controllers/admin/application_settings_controller.rb67
-rw-r--r--app/controllers/projects/prometheus/metrics_controller.rb2
-rw-r--r--app/helpers/application_settings_helper.rb16
-rw-r--r--app/models/deployment_metrics.rb12
-rw-r--r--app/models/environment.rb4
-rw-r--r--app/services/prometheus/adapter_service.rb30
-rw-r--r--config/routes/admin.rb3
-rw-r--r--doc/administration/instance_limits.md20
-rw-r--r--doc/administration/packages/container_registry.md12
-rw-r--r--doc/user/admin_area/settings/continuous_integration.md6
-rw-r--r--lib/gitlab/prometheus/adapter.rb34
-rw-r--r--locale/gitlab.pot12
-rw-r--r--spec/controllers/projects/prometheus/metrics_controller_spec.rb2
-rw-r--r--spec/finders/projects/serverless/functions_finder_spec.rb2
-rw-r--r--spec/helpers/application_settings_helper_spec.rb50
-rw-r--r--spec/lib/gitlab/prometheus/adapter_spec.rb (renamed from spec/services/prometheus/adapter_service_spec.rb)2
-rw-r--r--spec/models/environment_spec.rb2
-rw-r--r--spec/requests/self_monitoring_project_spec.rb175
-rw-r--r--spec/support/shared_examples/requests/self_monitoring_shared_examples.rb41
20 files changed, 448 insertions, 61 deletions
diff --git a/app/assets/javascripts/contextual_sidebar.js b/app/assets/javascripts/contextual_sidebar.js
index f43b6f3d777..51879f280e0 100644
--- a/app/assets/javascripts/contextual_sidebar.js
+++ b/app/assets/javascripts/contextual_sidebar.js
@@ -1,13 +1,9 @@
import $ from 'jquery';
import Cookies from 'js-cookie';
import _ from 'underscore';
-import bp from './breakpoints';
+import { GlBreakpointInstance as bp, breakpoints } from '@gitlab/ui/dist/utils';
import { parseBoolean } from '~/lib/utils/common_utils';
-// NOTE: at 1200px nav sidebar should not overlap the content
-// https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/24555#note_134136110
-const NAV_SIDEBAR_BREAKPOINT = 1200;
-
export const SIDEBAR_COLLAPSED_CLASS = 'js-sidebar-collapsed';
export default class ContextualSidebar {
@@ -50,9 +46,10 @@ export default class ContextualSidebar {
$(window).on('resize', () => _.debounce(this.render(), 100));
}
- // TODO: use the breakpoints from breakpoints.js once they have been updated for bootstrap 4
// See documentation: https://design.gitlab.com/regions/navigation#contextual-navigation
- static isDesktopBreakpoint = () => bp.windowWidth() >= NAV_SIDEBAR_BREAKPOINT;
+ // NOTE: at 1200px nav sidebar should not overlap the content
+ // https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/24555#note_134136110
+ static isDesktopBreakpoint = () => bp.windowWidth() >= breakpoints.xl;
static setCollapsedCookie(value) {
if (!ContextualSidebar.isDesktopBreakpoint()) {
return;
@@ -63,12 +60,13 @@ export default class ContextualSidebar {
toggleSidebarNav(show) {
const breakpoint = bp.getBreakpointSize();
const dbp = ContextualSidebar.isDesktopBreakpoint();
+ const supportedSizes = ['xs', 'sm', 'md'];
this.$sidebar.toggleClass(SIDEBAR_COLLAPSED_CLASS, !show);
this.$sidebar.toggleClass('sidebar-expanded-mobile', !dbp ? show : false);
this.$overlay.toggleClass(
'mobile-nav-open',
- breakpoint === 'xs' || breakpoint === 'sm' ? show : false,
+ supportedSizes.includes(breakpoint) ? show : false,
);
this.$sidebar.removeClass('sidebar-collapsed-desktop');
}
@@ -76,13 +74,14 @@ export default class ContextualSidebar {
toggleCollapsedSidebar(collapsed, saveCookie) {
const breakpoint = bp.getBreakpointSize();
const dbp = ContextualSidebar.isDesktopBreakpoint();
+ const supportedSizes = ['xs', 'sm', 'md'];
if (this.$sidebar.length) {
this.$sidebar.toggleClass(`sidebar-collapsed-desktop ${SIDEBAR_COLLAPSED_CLASS}`, collapsed);
this.$sidebar.toggleClass('sidebar-expanded-mobile', !dbp ? !collapsed : false);
this.$page.toggleClass(
'page-with-icon-sidebar',
- breakpoint === 'xs' || breakpoint === 'sm' ? true : collapsed,
+ supportedSizes.includes(breakpoint) ? true : collapsed,
);
}
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index 9d81d3fad07..58f088c6335 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -6,10 +6,21 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
before_action :set_application_setting
before_action :whitelist_query_limiting, only: [:usage_data]
+ before_action do
+ push_frontend_feature_flag(:self_monitoring_project)
+ end
+
VALID_SETTING_PANELS = %w(general integrations repository
ci_cd reporting metrics_and_profiling
network preferences).freeze
+ # The current size of a sidekiq job's jid is 24 characters. The size of the
+ # jid is an internal detail of Sidekiq, and they do not guarantee that it'll
+ # stay the same. We chose 50 to give us room in case the size of the jid
+ # increases. The jid is alphanumeric, so 50 is very generous. There is a spec
+ # that ensures that the constant value is more than the size of an actual jid.
+ PARAM_JOB_ID_MAX_SIZE = 50
+
VALID_SETTING_PANELS.each do |action|
define_method(action) { perform_update if submitted? }
end
@@ -62,8 +73,64 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
redirect_to ::Gitlab::LetsEncrypt.terms_of_service_url
end
+ def create_self_monitoring_project
+ return self_monitoring_project_not_implemented unless Feature.enabled?(:self_monitoring_project)
+
+ job_id = SelfMonitoringProjectCreateWorker.perform_async
+
+ render status: :accepted, json: {
+ job_id: job_id,
+ monitor_status: status_create_self_monitoring_project_admin_application_settings_path
+ }
+ end
+
+ def status_create_self_monitoring_project
+ return self_monitoring_project_not_implemented unless Feature.enabled?(:self_monitoring_project)
+
+ job_id = params[:job_id].to_s
+
+ unless job_id.length <= PARAM_JOB_ID_MAX_SIZE
+ return render status: :bad_request, json: {
+ message: _('Parameter "job_id" cannot exceed length of %{job_id_max_size}' %
+ { job_id_max_size: PARAM_JOB_ID_MAX_SIZE })
+ }
+ end
+
+ if Gitlab::CurrentSettings.instance_administration_project_id.present?
+ render status: :ok, json: self_monitoring_data
+
+ elsif SelfMonitoringProjectCreateWorker.in_progress?(job_id)
+ ::Gitlab::PollingInterval.set_header(response, interval: 3_000)
+
+ render status: :accepted, json: { message: _('Job is in progress') }
+
+ else
+ render status: :bad_request, json: {
+ message: _('Self-monitoring project does not exist. Please check logs ' \
+ 'for any error messages')
+ }
+ end
+ end
+
private
+ def self_monitoring_data
+ {
+ project_id: Gitlab::CurrentSettings.instance_administration_project_id,
+ project_full_path: Gitlab::CurrentSettings.instance_administration_project&.full_path
+ }
+ end
+
+ def self_monitoring_project_not_implemented
+ render(
+ status: :not_implemented,
+ json: {
+ message: _('Self-monitoring is not enabled on this GitLab server, contact your administrator.'),
+ documentation_url: help_page_path('administration/monitoring/gitlab_instance_administration_project/index')
+ }
+ )
+ end
+
def set_application_setting
@application_setting = ApplicationSetting.current_without_cache
end
diff --git a/app/controllers/projects/prometheus/metrics_controller.rb b/app/controllers/projects/prometheus/metrics_controller.rb
index f212ae52ecc..c9c7ba1253f 100644
--- a/app/controllers/projects/prometheus/metrics_controller.rb
+++ b/app/controllers/projects/prometheus/metrics_controller.rb
@@ -23,7 +23,7 @@ module Projects
private
def prometheus_adapter
- @prometheus_adapter ||= ::Prometheus::AdapterService.new(project, project.deployment_platform&.cluster).prometheus_adapter
+ @prometheus_adapter ||= ::Gitlab::Prometheus::Adapter.new(project, project.deployment_platform&.cluster).prometheus_adapter
end
def require_prometheus_metrics!
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index 71e4195c50f..d9a91f72dca 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -334,6 +334,22 @@ module ApplicationSettingsHelper
def omnibus_protected_paths_throttle?
Rack::Attack.throttles.key?('protected paths')
end
+
+ def self_monitoring_project_data
+ {
+ 'create_self_monitoring_project_path' =>
+ create_self_monitoring_project_admin_application_settings_path,
+
+ 'status_create_self_monitoring_project_path' =>
+ status_create_self_monitoring_project_admin_application_settings_path,
+
+ 'self_monitoring_project_exists' =>
+ Gitlab::CurrentSettings.instance_administration_project.present?,
+
+ 'self_monitoring_project_full_path' =>
+ Gitlab::CurrentSettings.instance_administration_project&.full_path
+ }
+ end
end
ApplicationSettingsHelper.prepend_if_ee('EE::ApplicationSettingsHelper') # rubocop: disable Cop/InjectEnterpriseEditionModule
diff --git a/app/models/deployment_metrics.rb b/app/models/deployment_metrics.rb
index 20f0ec3e9b6..c5f8b03f25b 100644
--- a/app/models/deployment_metrics.rb
+++ b/app/models/deployment_metrics.rb
@@ -34,20 +34,10 @@ class DeploymentMetrics
def prometheus_adapter
strong_memoize(:prometheus_adapter) do
- service = project.find_or_initialize_service('prometheus')
-
- if service.can_query?
- service
- else
- cluster_prometheus
- end
+ Gitlab::Prometheus::Adapter.new(project, cluster).prometheus_adapter
end
end
- def cluster_prometheus
- cluster.application_prometheus if cluster&.application_prometheus_available?
- end
-
def has_metrics_and_can_query?
has_metrics? && prometheus_adapter.can_query?
end
diff --git a/app/models/environment.rb b/app/models/environment.rb
index d54050cd156..2d480345b5a 100644
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -225,11 +225,9 @@ class Environment < ApplicationRecord
prometheus_adapter.query(:additional_metrics_environment, self, *args.map(&:to_f))
end
- # rubocop: disable CodeReuse/ServiceClass
def prometheus_adapter
- @prometheus_adapter ||= Prometheus::AdapterService.new(project, deployment_platform&.cluster).prometheus_adapter
+ @prometheus_adapter ||= Gitlab::Prometheus::Adapter.new(project, deployment_platform&.cluster).prometheus_adapter
end
- # rubocop: enable CodeReuse/ServiceClass
def slug
super.presence || generate_slug
diff --git a/app/services/prometheus/adapter_service.rb b/app/services/prometheus/adapter_service.rb
deleted file mode 100644
index 5e8357a83f6..00000000000
--- a/app/services/prometheus/adapter_service.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: true
-
-module Prometheus
- class AdapterService
- attr_reader :project, :cluster
-
- def initialize(project, cluster)
- @project = project
- @cluster = cluster
- end
-
- def prometheus_adapter
- @prometheus_adapter ||= if service_prometheus_adapter.can_query?
- service_prometheus_adapter
- else
- cluster_prometheus_adapter
- end
- end
-
- def service_prometheus_adapter
- project.find_or_initialize_service('prometheus')
- end
-
- def cluster_prometheus_adapter
- application = cluster&.application_prometheus
-
- application if application&.available?
- end
- end
-end
diff --git a/config/routes/admin.rb b/config/routes/admin.rb
index 34660358234..c58b74ecfec 100644
--- a/config/routes/admin.rb
+++ b/config/routes/admin.rb
@@ -116,6 +116,9 @@ namespace :admin do
put :clear_repository_check_states
match :general, :integrations, :repository, :ci_cd, :reporting, :metrics_and_profiling, :network, :preferences, via: [:get, :patch]
get :lets_encrypt_terms_of_service
+
+ post :create_self_monitoring_project
+ get :status_create_self_monitoring_project
end
resources :labels
diff --git a/doc/administration/instance_limits.md b/doc/administration/instance_limits.md
new file mode 100644
index 00000000000..3e2f6caf328
--- /dev/null
+++ b/doc/administration/instance_limits.md
@@ -0,0 +1,20 @@
+---
+type: reference
+---
+
+# GitLab application limits
+
+GitLab, like most large applications, enforces limits within certain features to maintain a
+minimum quality of performance. Allowing some features to be limitless could affect security,
+performance, data, or could even exhaust the allocated resources for the application.
+
+## Number of comments per issue, merge request or commit
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/22388) in GitLab 12.4.
+
+There's a limit to the number of comments that can be submitted on an issue,
+merge request, or commit. When the limit is reached, system notes can still be
+added so that the history of events is not lost, but user-submitted comments
+will fail.
+
+- **Max limit:** 5.000 comments
diff --git a/doc/administration/packages/container_registry.md b/doc/administration/packages/container_registry.md
index 2e97849eda2..0c6caed4e55 100644
--- a/doc/administration/packages/container_registry.md
+++ b/doc/administration/packages/container_registry.md
@@ -398,6 +398,9 @@ To configure the `s3` storage driver in Omnibus:
1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect.
+NOTE: **Note:**
+`your-s3-bucket` should only be the name of a bucket that exists, and can't include subdirectories.
+
**Installations from source**
Configuring the storage driver is done in your registry config YML file created
@@ -408,9 +411,9 @@ when you [deployed your docker registry](https://docs.docker.com/registry/deploy
```yml
storage:
s3:
- accesskey: 'AKIAKIAKI'
- secretkey: 'secret123'
- bucket: 'gitlab-registry-bucket-AKIAKIAKI'
+ accesskey: 's3-access-key'
+ secretkey: 's3-secret-key-for-access-key'
+ bucket: 'your-s3-bucket'
region: 'your-s3-region'
regionendpoint: 'your-s3-regionendpoint'
cache:
@@ -419,6 +422,9 @@ storage:
enabled: true
```
+NOTE: **Note:**
+`your-s3-bucket` should only be the name of a bucket that exists, and can't include subdirectories.
+
## Change the registry's internal port
NOTE: **Note:**
diff --git a/doc/user/admin_area/settings/continuous_integration.md b/doc/user/admin_area/settings/continuous_integration.md
index 79deda73d34..f6b7da384bc 100644
--- a/doc/user/admin_area/settings/continuous_integration.md
+++ b/doc/user/admin_area/settings/continuous_integration.md
@@ -78,6 +78,12 @@ This setting is set per job and can be overridden in
[`.gitlab-ci.yml`](../../../ci/yaml/README.md#artifactsexpire_in).
To disable the expiration, set it to `0`. The default unit is in seconds.
+NOTE: **Note**
+Any changes to this setting will apply to new artifacts only. The expiration time will not
+be updated for artifacts created before this setting was changed.
+The administrator may need to manually search for and expire previously-created
+artifacts, as described in the [troubleshooting documentation](../../../administration/troubleshooting/gitlab_rails_cheat_sheet.md#remove-artifacts-more-than-a-week-old).
+
## Shared Runners pipeline minutes quota **(STARTER ONLY)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/1078)
diff --git a/lib/gitlab/prometheus/adapter.rb b/lib/gitlab/prometheus/adapter.rb
new file mode 100644
index 00000000000..ed10ef2917f
--- /dev/null
+++ b/lib/gitlab/prometheus/adapter.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Prometheus
+ class Adapter
+ attr_reader :project, :cluster
+
+ def initialize(project, cluster)
+ @project = project
+ @cluster = cluster
+ end
+
+ def prometheus_adapter
+ @prometheus_adapter ||= if service_prometheus_adapter.can_query?
+ service_prometheus_adapter
+ else
+ cluster_prometheus_adapter
+ end
+ end
+
+ def cluster_prometheus_adapter
+ application = cluster&.application_prometheus
+
+ application if application&.available?
+ end
+
+ private
+
+ def service_prometheus_adapter
+ project.find_or_initialize_service('prometheus')
+ end
+ end
+ end
+end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 02aa7a7933e..9830a6ce80d 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -10197,6 +10197,9 @@ msgstr ""
msgid "Job has wrong arguments format."
msgstr ""
+msgid "Job is in progress"
+msgstr ""
+
msgid "Job is missing the `model_type` argument."
msgstr ""
@@ -12714,6 +12717,9 @@ msgstr ""
msgid "Parameter"
msgstr ""
+msgid "Parameter \"job_id\" cannot exceed length of %{job_id_max_size}"
+msgstr ""
+
msgid "Parent epic doesn't exist."
msgstr ""
@@ -16217,6 +16223,12 @@ msgstr ""
msgid "Selecting a GitLab user will add a link to the GitLab user in the descriptions of issues and comments (e.g. \"By <a href=\"#\">@johnsmith</a>\"). It will also associate and/or assign these issues and comments with the selected user."
msgstr ""
+msgid "Self-monitoring is not enabled on this GitLab server, contact your administrator."
+msgstr ""
+
+msgid "Self-monitoring project does not exist. Please check logs for any error messages"
+msgstr ""
+
msgid "Send a separate email notification to Developers."
msgstr ""
diff --git a/spec/controllers/projects/prometheus/metrics_controller_spec.rb b/spec/controllers/projects/prometheus/metrics_controller_spec.rb
index afdb8bbc983..157948de29d 100644
--- a/spec/controllers/projects/prometheus/metrics_controller_spec.rb
+++ b/spec/controllers/projects/prometheus/metrics_controller_spec.rb
@@ -85,7 +85,7 @@ describe Projects::Prometheus::MetricsController do
end
it 'calls prometheus adapter service' do
- expect_next_instance_of(::Prometheus::AdapterService) do |instance|
+ expect_next_instance_of(::Gitlab::Prometheus::Adapter) do |instance|
expect(instance).to receive(:prometheus_adapter)
end
diff --git a/spec/finders/projects/serverless/functions_finder_spec.rb b/spec/finders/projects/serverless/functions_finder_spec.rb
index dcf1b2045ab..d5644daebab 100644
--- a/spec/finders/projects/serverless/functions_finder_spec.rb
+++ b/spec/finders/projects/serverless/functions_finder_spec.rb
@@ -108,7 +108,7 @@ describe Projects::Serverless::FunctionsFinder do
let(:finder) { described_class.new(project) }
before do
- allow(Prometheus::AdapterService).to receive(:new).and_return(double(prometheus_adapter: prometheus_adapter))
+ allow(Gitlab::Prometheus::Adapter).to receive(:new).and_return(double(prometheus_adapter: prometheus_adapter))
allow(prometheus_adapter).to receive(:query).and_return(prometheus_empty_body('matrix'))
end
diff --git a/spec/helpers/application_settings_helper_spec.rb b/spec/helpers/application_settings_helper_spec.rb
index 8303c4eafbe..629ac34edc1 100644
--- a/spec/helpers/application_settings_helper_spec.rb
+++ b/spec/helpers/application_settings_helper_spec.rb
@@ -59,4 +59,54 @@ describe ApplicationSettingsHelper do
expect(helper.integration_expanded?('plantuml_')).to be_falsey
end
end
+
+ describe '.self_monitoring_project_data' do
+ context 'when self monitoring project does not exist' do
+ it 'returns create_self_monitoring_project_path' do
+ expect(helper.self_monitoring_project_data).to include(
+ 'create_self_monitoring_project_path' =>
+ create_self_monitoring_project_admin_application_settings_path
+ )
+ end
+
+ it 'returns status_create_self_monitoring_project_path' do
+ expect(helper.self_monitoring_project_data).to include(
+ 'status_create_self_monitoring_project_path' =>
+ status_create_self_monitoring_project_admin_application_settings_path
+ )
+ end
+
+ it 'returns self_monitoring_project_exists false' do
+ expect(helper.self_monitoring_project_data).to include(
+ 'self_monitoring_project_exists' => false
+ )
+ end
+
+ it 'returns nil for project full_path' do
+ expect(helper.self_monitoring_project_data).to include(
+ 'self_monitoring_project_full_path' => nil
+ )
+ end
+ end
+
+ context 'when self monitoring project exists' do
+ let(:project) { build(:project) }
+
+ before do
+ stub_application_setting(instance_administration_project: project)
+ end
+
+ it 'returns self_monitoring_project_exists true' do
+ expect(helper.self_monitoring_project_data).to include(
+ 'self_monitoring_project_exists' => true
+ )
+ end
+
+ it 'returns project full_path' do
+ expect(helper.self_monitoring_project_data).to include(
+ 'self_monitoring_project_full_path' => project.full_path
+ )
+ end
+ end
+ end
end
diff --git a/spec/services/prometheus/adapter_service_spec.rb b/spec/lib/gitlab/prometheus/adapter_spec.rb
index 3c075fc1581..202bf65f92b 100644
--- a/spec/services/prometheus/adapter_service_spec.rb
+++ b/spec/lib/gitlab/prometheus/adapter_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Prometheus::AdapterService do
+describe Gitlab::Prometheus::Adapter do
let_it_be(:project) { create(:project) }
let_it_be(:cluster, reload: true) { create(:cluster, :provided_by_user, environment_scope: '*', projects: [project]) }
diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb
index 462e9a56f5c..af7ab24d7d6 100644
--- a/spec/models/environment_spec.rb
+++ b/spec/models/environment_spec.rb
@@ -1112,7 +1112,7 @@ describe Environment, :use_clean_rails_memory_store_caching do
describe '#prometheus_adapter' do
it 'calls prometheus adapter service' do
- expect_next_instance_of(Prometheus::AdapterService) do |instance|
+ expect_next_instance_of(Gitlab::Prometheus::Adapter) do |instance|
expect(instance).to receive(:prometheus_adapter)
end
diff --git a/spec/requests/self_monitoring_project_spec.rb b/spec/requests/self_monitoring_project_spec.rb
new file mode 100644
index 00000000000..be701d74675
--- /dev/null
+++ b/spec/requests/self_monitoring_project_spec.rb
@@ -0,0 +1,175 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'Self-Monitoring project requests' do
+ let(:admin) { create(:admin) }
+
+ describe 'POST #create_self_monitoring_project' do
+ let(:worker_class) { SelfMonitoringProjectCreateWorker }
+
+ subject { post create_self_monitoring_project_admin_application_settings_path }
+
+ it_behaves_like 'not accessible to non-admin users'
+
+ context 'with admin user' do
+ before do
+ login_as(admin)
+ end
+
+ context 'with feature flag disabled' do
+ it_behaves_like 'not accessible if feature flag is disabled'
+ end
+
+ context 'with feature flag enabled' do
+ it 'returns sidekiq job_id of expected length' do
+ subject
+
+ job_id = json_response['job_id']
+
+ aggregate_failures do
+ expect(job_id).to be_present
+ expect(job_id.length).to be <= Admin::ApplicationSettingsController::PARAM_JOB_ID_MAX_SIZE
+ end
+ end
+
+ it 'triggers async worker' do
+ expect(worker_class).to receive(:perform_async)
+
+ subject
+ end
+
+ it 'returns accepted response' do
+ subject
+
+ aggregate_failures do
+ expect(response).to have_gitlab_http_status(:accepted)
+ expect(json_response.keys).to contain_exactly('job_id', 'monitor_status')
+ expect(json_response).to include(
+ 'monitor_status' => status_create_self_monitoring_project_admin_application_settings_path
+ )
+ end
+ end
+
+ it 'returns job_id' do
+ fake_job_id = 'b5b28910d97563e58c2fe55f'
+ expect(worker_class).to receive(:perform_async).and_return(fake_job_id)
+
+ subject
+ response_job_id = json_response['job_id']
+
+ expect(response_job_id).to eq fake_job_id
+ end
+ end
+ end
+ end
+
+ describe 'GET #status_create_self_monitoring_project' do
+ let(:worker_class) { SelfMonitoringProjectCreateWorker }
+ let(:job_id) { 'job_id' }
+
+ subject do
+ get status_create_self_monitoring_project_admin_application_settings_path,
+ params: { job_id: job_id }
+ end
+
+ it_behaves_like 'not accessible to non-admin users'
+
+ context 'with admin user' do
+ before do
+ login_as(admin)
+ end
+
+ context 'with feature flag disabled' do
+ it_behaves_like 'not accessible if feature flag is disabled'
+ end
+
+ context 'with feature flag enabled' do
+ context 'with invalid job_id' do
+ it 'returns bad_request if job_id too long' do
+ get status_create_self_monitoring_project_admin_application_settings_path,
+ params: { job_id: 'a' * 51 }
+
+ aggregate_failures do
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response).to eq('message' => 'Parameter "job_id" cannot ' \
+ "exceed length of #{Admin::ApplicationSettingsController::PARAM_JOB_ID_MAX_SIZE}")
+ end
+ end
+ end
+
+ context 'when self-monitoring project exists' do
+ let(:project) { build(:project) }
+
+ before do
+ stub_application_setting(instance_administration_project_id: 1)
+ stub_application_setting(instance_administration_project: project)
+ end
+
+ it 'does not need job_id' do
+ get status_create_self_monitoring_project_admin_application_settings_path
+
+ aggregate_failures do
+ expect(response).to have_gitlab_http_status(:success)
+ expect(json_response).to eq(
+ 'project_id' => 1,
+ 'project_full_path' => project.full_path
+ )
+ end
+ end
+
+ it 'returns success' do
+ subject
+
+ aggregate_failures do
+ expect(response).to have_gitlab_http_status(:success)
+ expect(json_response).to eq(
+ 'project_id' => 1,
+ 'project_full_path' => project.full_path
+ )
+ end
+ end
+ end
+
+ context 'when job is in progress' do
+ before do
+ allow(worker_class).to receive(:in_progress?)
+ .with(job_id)
+ .and_return(true)
+ end
+
+ it 'sets polling header' do
+ expect(::Gitlab::PollingInterval).to receive(:set_header)
+
+ subject
+ end
+
+ it 'returns accepted' do
+ subject
+
+ aggregate_failures do
+ expect(response).to have_gitlab_http_status(:accepted)
+ expect(json_response).to eq('message' => 'Job is in progress')
+ end
+ end
+ end
+
+ context 'when self-monitoring project and job do not exist' do
+ let(:job_id) { nil }
+
+ it 'returns bad_request' do
+ subject
+
+ aggregate_failures do
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response).to eq(
+ 'message' => 'Self-monitoring project does not exist. Please check ' \
+ 'logs for any error messages'
+ )
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/support/shared_examples/requests/self_monitoring_shared_examples.rb b/spec/support/shared_examples/requests/self_monitoring_shared_examples.rb
new file mode 100644
index 00000000000..6dea7fcda3c
--- /dev/null
+++ b/spec/support/shared_examples/requests/self_monitoring_shared_examples.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'not accessible if feature flag is disabled' do
+ before do
+ stub_feature_flags(self_monitoring_project: false)
+ end
+
+ it 'returns not_implemented' do
+ subject
+
+ aggregate_failures do
+ expect(response).to have_gitlab_http_status(:not_implemented)
+ expect(json_response).to eq(
+ 'message' => _('Self-monitoring is not enabled on this GitLab server, contact your administrator.'),
+ 'documentation_url' => help_page_path('administration/monitoring/gitlab_instance_administration_project/index')
+ )
+ end
+ end
+end
+
+RSpec.shared_examples 'not accessible to non-admin users' do
+ context 'with unauthenticated user' do
+ it 'redirects to signin page' do
+ subject
+
+ expect(response).to redirect_to(new_user_session_path)
+ end
+ end
+
+ context 'with authenticated non-admin user' do
+ before do
+ login_as(create(:user))
+ end
+
+ it 'returns status not_found' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+end