summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-05-04 03:09:50 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-05-04 03:09:50 +0000
commit21be9646a94e2c145897e25d9c521523d55e1614 (patch)
tree2873c5461d2222f9e51ba9cea9d2ed87d3f87e20
parent933d8b6d85b56a2f0f9d8ffe54f0212422537b03 (diff)
downloadgitlab-ce-21be9646a94e2c145897e25d9c521523d55e1614.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/models/clusters/applications/ingress.rb5
-rw-r--r--app/models/clusters/cluster.rb1
-rw-r--r--app/services/clusters/applications/ingress_modsecurity_usage_service.rb69
-rw-r--r--changelogs/unreleased/32358-add-initial-stats-for-modsecurity-installations.yml5
-rw-r--r--db/migrate/20200402115013_add_index_on_modsecurity_to_ingress.rb18
-rw-r--r--db/migrate/20200402115623_add_index_on_successful_deployment_and_environment_id_to_deployments.rb18
-rw-r--r--db/migrate/20200420141733_add_index_on_enabled_clusters.rb18
-rw-r--r--db/structure.sql9
-rw-r--r--doc/api/pipelines.md2
-rw-r--r--doc/user/admin_area/settings/usage_statistics.md2
-rw-r--r--lib/gitlab/database/batch_count.rb8
-rw-r--r--lib/gitlab/usage_data.rb26
-rw-r--r--spec/factories/clusters/applications/helm.rb18
-rw-r--r--spec/lib/gitlab/database/batch_count_spec.rb8
-rw-r--r--spec/lib/gitlab/usage_data_spec.rb138
-rw-r--r--spec/services/clusters/applications/ingress_modsecurity_usage_service_spec.rb196
16 files changed, 261 insertions, 280 deletions
diff --git a/app/models/clusters/applications/ingress.rb b/app/models/clusters/applications/ingress.rb
index d8f90e15c42..dd354198910 100644
--- a/app/models/clusters/applications/ingress.rb
+++ b/app/models/clusters/applications/ingress.rb
@@ -17,6 +17,7 @@ module Clusters
include ::Clusters::Concerns::ApplicationVersion
include ::Clusters::Concerns::ApplicationData
include AfterCommitQueue
+ include UsageStatistics
default_value_for :ingress_type, :nginx
default_value_for :modsecurity_enabled, true
@@ -29,6 +30,10 @@ module Clusters
enum modsecurity_mode: { logging: 0, blocking: 1 }
+ scope :modsecurity_not_installed, -> { where(modsecurity_enabled: nil) }
+ scope :modsecurity_enabled, -> { where(modsecurity_enabled: true) }
+ scope :modsecurity_disabled, -> { where(modsecurity_enabled: false) }
+
FETCH_IP_ADDRESS_DELAY = 30.seconds
state_machine :status do
diff --git a/app/models/clusters/cluster.rb b/app/models/clusters/cluster.rb
index 78dd876020b..b21f9137d59 100644
--- a/app/models/clusters/cluster.rb
+++ b/app/models/clusters/cluster.rb
@@ -35,6 +35,7 @@ module Clusters
has_many :projects, through: :cluster_projects, class_name: '::Project'
has_one :cluster_project, -> { order(id: :desc) }, class_name: 'Clusters::Project'
has_many :deployment_clusters
+ has_many :deployments, inverse_of: :cluster
has_many :cluster_groups, class_name: 'Clusters::Group'
has_many :groups, through: :cluster_groups, class_name: '::Group'
diff --git a/app/services/clusters/applications/ingress_modsecurity_usage_service.rb b/app/services/clusters/applications/ingress_modsecurity_usage_service.rb
deleted file mode 100644
index 4aac8bb3cbd..00000000000
--- a/app/services/clusters/applications/ingress_modsecurity_usage_service.rb
+++ /dev/null
@@ -1,69 +0,0 @@
-# frozen_string_literal: true
-
-# rubocop: disable CodeReuse/ActiveRecord
-module Clusters
- module Applications
- ##
- # This service measures usage of the Modsecurity Web Application Firewall across the entire
- # instance's deployed environments.
- #
- # The default configuration is`AUTO_DEVOPS_MODSECURITY_SEC_RULE_ENGINE=DetectionOnly` so we
- # measure non-default values via definition of either ci_variables or ci_pipeline_variables.
- # Since both these values are encrypted, we must decrypt and count them in memory.
- #
- # NOTE: this service is an approximation as it does not yet take into account `environment_scope` or `ci_group_variables`.
- ##
- class IngressModsecurityUsageService
- ADO_MODSEC_KEY = "AUTO_DEVOPS_MODSECURITY_SEC_RULE_ENGINE"
-
- def initialize(blocking_count: 0, disabled_count: 0)
- @blocking_count = blocking_count
- @disabled_count = disabled_count
- end
-
- def execute
- conditions = -> { merge(::Environment.available).merge(::Deployment.success).where(key: ADO_MODSEC_KEY) }
-
- ci_pipeline_var_enabled =
- ::Ci::PipelineVariable
- .joins(pipeline: { environments: :last_visible_deployment })
- .merge(conditions)
- .order('deployments.environment_id, deployments.id DESC')
-
- ci_var_enabled =
- ::Ci::Variable
- .joins(project: { environments: :last_visible_deployment })
- .merge(conditions)
- .merge(
- # Give priority to pipeline variables by excluding from dataset
- ::Ci::Variable.joins(project: :environments).where.not(
- environments: { id: ci_pipeline_var_enabled.select('DISTINCT ON (deployments.environment_id) deployments.environment_id') }
- )
- ).select('DISTINCT ON (deployments.environment_id) ci_variables.*')
-
- sum_modsec_config_counts(
- ci_pipeline_var_enabled.select('DISTINCT ON (deployments.environment_id) ci_pipeline_variables.*')
- )
- sum_modsec_config_counts(ci_var_enabled)
-
- {
- ingress_modsecurity_blocking: @blocking_count,
- ingress_modsecurity_disabled: @disabled_count
- }
- end
-
- private
-
- # These are encrypted so we must decrypt and count in memory
- def sum_modsec_config_counts(dataset)
- dataset.each do |var|
- case var.value
- when "On" then @blocking_count += 1
- when "Off" then @disabled_count += 1
- # `else` could be default or any unsupported user input
- end
- end
- end
- end
- end
-end
diff --git a/changelogs/unreleased/32358-add-initial-stats-for-modsecurity-installations.yml b/changelogs/unreleased/32358-add-initial-stats-for-modsecurity-installations.yml
new file mode 100644
index 00000000000..cbb0098c718
--- /dev/null
+++ b/changelogs/unreleased/32358-add-initial-stats-for-modsecurity-installations.yml
@@ -0,0 +1,5 @@
+---
+title: Add indexes on ingress, enabled clusters and successful deployments
+merge_request: 28331
+author:
+type: performance
diff --git a/db/migrate/20200402115013_add_index_on_modsecurity_to_ingress.rb b/db/migrate/20200402115013_add_index_on_modsecurity_to_ingress.rb
new file mode 100644
index 00000000000..8bd2d957092
--- /dev/null
+++ b/db/migrate/20200402115013_add_index_on_modsecurity_to_ingress.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class AddIndexOnModsecurityToIngress < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ INDEX_NAME = 'index_clusters_applications_ingress_on_modsecurity'
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :clusters_applications_ingress, [:modsecurity_enabled, :modsecurity_mode, :cluster_id], name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index :clusters_applications_ingress, [:modsecurity_enabled, :modsecurity_mode, :cluster_id], name: INDEX_NAME
+ end
+end
diff --git a/db/migrate/20200402115623_add_index_on_successful_deployment_and_environment_id_to_deployments.rb b/db/migrate/20200402115623_add_index_on_successful_deployment_and_environment_id_to_deployments.rb
new file mode 100644
index 00000000000..c86f7ad63f0
--- /dev/null
+++ b/db/migrate/20200402115623_add_index_on_successful_deployment_and_environment_id_to_deployments.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class AddIndexOnSuccessfulDeploymentAndEnvironmentIdToDeployments < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ INDEX_NAME = 'index_successful_deployments_on_cluster_id_and_environment_id'
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :deployments, [:cluster_id, :environment_id], where: 'status = 2', name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index :deployments, [:cluster_id, :environment_id], where: 'status = 2', name: INDEX_NAME
+ end
+end
diff --git a/db/migrate/20200420141733_add_index_on_enabled_clusters.rb b/db/migrate/20200420141733_add_index_on_enabled_clusters.rb
new file mode 100644
index 00000000000..43f4b072c82
--- /dev/null
+++ b/db/migrate/20200420141733_add_index_on_enabled_clusters.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+class AddIndexOnEnabledClusters < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ INDEX_NAME = 'index_enabled_clusters_on_id'
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :clusters, [:id], where: 'enabled = true', name: INDEX_NAME
+ end
+
+ def down
+ remove_concurrent_index :clusters, [:id], where: 'enabled = true', name: INDEX_NAME
+ end
+end
diff --git a/db/structure.sql b/db/structure.sql
index c0a222b61df..11ceb670805 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -9289,6 +9289,8 @@ CREATE UNIQUE INDEX index_clusters_applications_helm_on_cluster_id ON public.clu
CREATE UNIQUE INDEX index_clusters_applications_ingress_on_cluster_id ON public.clusters_applications_ingress USING btree (cluster_id);
+CREATE INDEX index_clusters_applications_ingress_on_modsecurity ON public.clusters_applications_ingress USING btree (modsecurity_enabled, modsecurity_mode, cluster_id);
+
CREATE UNIQUE INDEX index_clusters_applications_jupyter_on_cluster_id ON public.clusters_applications_jupyter USING btree (cluster_id);
CREATE INDEX index_clusters_applications_jupyter_on_oauth_application_id ON public.clusters_applications_jupyter USING btree (oauth_application_id);
@@ -9421,6 +9423,8 @@ CREATE UNIQUE INDEX index_emails_on_email ON public.emails USING btree (email);
CREATE INDEX index_emails_on_user_id ON public.emails USING btree (user_id);
+CREATE INDEX index_enabled_clusters_on_id ON public.clusters USING btree (id) WHERE (enabled = true);
+
CREATE INDEX index_environments_on_auto_stop_at ON public.environments USING btree (auto_stop_at) WHERE (auto_stop_at IS NOT NULL);
CREATE INDEX index_environments_on_name_varchar_pattern_ops ON public.environments USING btree (name varchar_pattern_ops);
@@ -10525,6 +10529,8 @@ CREATE INDEX index_subscriptions_on_project_id ON public.subscriptions USING btr
CREATE UNIQUE INDEX index_subscriptions_on_subscribable_and_user_id_and_project_id ON public.subscriptions USING btree (subscribable_id, subscribable_type, user_id, project_id);
+CREATE INDEX index_successful_deployments_on_cluster_id_and_environment_id ON public.deployments USING btree (cluster_id, environment_id) WHERE (status = 2);
+
CREATE UNIQUE INDEX index_suggestions_on_note_id_and_relative_order ON public.suggestions USING btree (note_id, relative_order);
CREATE UNIQUE INDEX index_system_note_metadata_on_description_version_id ON public.system_note_metadata USING btree (description_version_id) WHERE (description_version_id IS NOT NULL);
@@ -13542,6 +13548,8 @@ COPY "schema_migrations" (version) FROM STDIN;
20200401095430
20200401211005
20200402001106
+20200402115013
+20200402115623
20200402123926
20200402124802
20200402135250
@@ -13607,6 +13615,7 @@ COPY "schema_migrations" (version) FROM STDIN;
20200420104303
20200420104323
20200420115948
+20200420141733
20200420162730
20200420172113
20200420172752
diff --git a/doc/api/pipelines.md b/doc/api/pipelines.md
index 5b67df14ace..a4245ec02aa 100644
--- a/doc/api/pipelines.md
+++ b/doc/api/pipelines.md
@@ -225,7 +225,7 @@ Response:
}
```
-## Cancel a pipelines jobs
+## Cancel a pipeline's jobs
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/5837) in GitLab 8.11
diff --git a/doc/user/admin_area/settings/usage_statistics.md b/doc/user/admin_area/settings/usage_statistics.md
index 1f01a364514..f9a45fadf6d 100644
--- a/doc/user/admin_area/settings/usage_statistics.md
+++ b/doc/user/admin_area/settings/usage_statistics.md
@@ -304,8 +304,10 @@ but commented out to help encourage others to add to it in the future. -->
|licenses_list_views|counts||
|user_preferences_group_overview_details|counts||
|user_preferences_group_overview_security_dashboard|counts||
+|ingress_modsecurity_logging|counts||
|ingress_modsecurity_blocking|counts||
|ingress_modsecurity_disabled|counts||
+|ingress_modsecurity_not_installed|counts||
|dependency_list_usages_total|counts||
|epics|counts||
|feature_flags|counts||
diff --git a/lib/gitlab/database/batch_count.rb b/lib/gitlab/database/batch_count.rb
index 2359dceae48..ab069ce1da1 100644
--- a/lib/gitlab/database/batch_count.rb
+++ b/lib/gitlab/database/batch_count.rb
@@ -91,11 +91,17 @@ module Gitlab
def batch_fetch(start, finish, mode)
# rubocop:disable GitlabSecurity/PublicSend
- @relation.select(@column).public_send(mode).where(@column => start..(finish - 1)).count
+ @relation.select(@column).public_send(mode).where(between_condition(start, finish)).count
end
private
+ def between_condition(start, finish)
+ return @column.between(start..(finish - 1)) if @column.is_a?(Arel::Attributes::Attribute)
+
+ { @column => start..(finish - 1) }
+ end
+
def actual_start(start)
start || @relation.minimum(@column) || 0
end
diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb
index 68e70ecf8e1..f05825d2be1 100644
--- a/lib/gitlab/usage_data.rb
+++ b/lib/gitlab/usage_data.rb
@@ -273,7 +273,24 @@ module Gitlab
end
def ingress_modsecurity_usage
- ::Clusters::Applications::IngressModsecurityUsageService.new.execute
+ ##
+ # This method measures usage of the Modsecurity Web Application Firewall across the entire
+ # instance's deployed environments.
+ #
+ # NOTE: this service is an approximation as it does not yet take into account if environment
+ # is enabled and only measures applications installed using GitLab Managed Apps (disregards
+ # CI-based managed apps).
+ #
+ # More details: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28331#note_318621786
+ ##
+
+ column = ::Deployment.arel_table[:environment_id]
+ {
+ ingress_modsecurity_logging: distinct_count(successful_deployments_with_cluster(::Clusters::Applications::Ingress.modsecurity_enabled.logging), column),
+ ingress_modsecurity_blocking: distinct_count(successful_deployments_with_cluster(::Clusters::Applications::Ingress.modsecurity_enabled.blocking), column),
+ ingress_modsecurity_disabled: distinct_count(successful_deployments_with_cluster(::Clusters::Applications::Ingress.modsecurity_disabled), column),
+ ingress_modsecurity_not_installed: distinct_count(successful_deployments_with_cluster(::Clusters::Applications::Ingress.modsecurity_not_installed), column)
+ }
end
# rubocop: disable CodeReuse/ActiveRecord
@@ -318,6 +335,13 @@ module Gitlab
rescue ActiveRecord::StatementInvalid
{ projects_jira_server_active: -1, projects_jira_cloud_active: -1, projects_jira_active: -1 }
end
+
+ def successful_deployments_with_cluster(scope)
+ scope
+ .joins(cluster: :deployments)
+ .merge(Clusters::Cluster.enabled)
+ .merge(Deployment.success)
+ end
# rubocop: enable CodeReuse/ActiveRecord
def jira_import_usage
diff --git a/spec/factories/clusters/applications/helm.rb b/spec/factories/clusters/applications/helm.rb
index 0152b16c8ea..7e52c54d4f1 100644
--- a/spec/factories/clusters/applications/helm.rb
+++ b/spec/factories/clusters/applications/helm.rb
@@ -77,6 +77,24 @@ FactoryBot.define do
trait :no_helm_installed do
cluster factory: %i(cluster provided_by_gcp)
end
+
+ trait :modsecurity_blocking do
+ modsecurity_enabled { true }
+ modsecurity_mode { :blocking }
+ end
+
+ trait :modsecurity_logging do
+ modsecurity_enabled { true }
+ modsecurity_mode { :logging }
+ end
+
+ trait :modsecurity_disabled do
+ modsecurity_enabled { false }
+ end
+
+ trait :modsecurity_not_installed do
+ modsecurity_enabled { nil }
+ end
end
factory :clusters_applications_cert_manager, class: 'Clusters::Applications::CertManager' do
diff --git a/spec/lib/gitlab/database/batch_count_spec.rb b/spec/lib/gitlab/database/batch_count_spec.rb
index 7be84b8f980..e7cb53f2dbd 100644
--- a/spec/lib/gitlab/database/batch_count_spec.rb
+++ b/spec/lib/gitlab/database/batch_count_spec.rb
@@ -35,6 +35,10 @@ describe Gitlab::Database::BatchCount do
expect(described_class.batch_count(model, "#{model.table_name}.id")).to eq(5)
end
+ it 'counts with Arel column' do
+ expect(described_class.batch_count(model, model.arel_table[:id])).to eq(5)
+ end
+
it 'counts table with batch_size 50K' do
expect(described_class.batch_count(model, batch_size: 50_000)).to eq(5)
end
@@ -98,6 +102,10 @@ describe Gitlab::Database::BatchCount do
expect(described_class.batch_distinct_count(model, "#{model.table_name}.#{column}")).to eq(2)
end
+ it 'counts with Arel column' do
+ expect(described_class.batch_distinct_count(model, model.arel_table[column])).to eq(2)
+ end
+
it 'counts with :column field with batch_size of 50K' do
expect(described_class.batch_distinct_count(model, column, batch_size: 50_000)).to eq(2)
end
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index 858ee360d8a..ddbc4240f10 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -319,18 +319,132 @@ describe Gitlab::UsageData, :aggregate_failures do
describe '#ingress_modsecurity_usage' do
subject { described_class.ingress_modsecurity_usage }
- it 'gathers variable data' do
- allow_any_instance_of(
- ::Clusters::Applications::IngressModsecurityUsageService
- ).to receive(:execute).and_return(
- {
- ingress_modsecurity_blocking: 1,
- ingress_modsecurity_disabled: 2
- }
- )
-
- expect(subject[:ingress_modsecurity_blocking]).to eq(1)
- expect(subject[:ingress_modsecurity_disabled]).to eq(2)
+ let(:environment) { create(:environment) }
+ let(:project) { environment.project }
+ let(:environment_scope) { '*' }
+ let(:deployment) { create(:deployment, :success, environment: environment, project: project, cluster: cluster) }
+ let(:cluster) { create(:cluster, environment_scope: environment_scope, projects: [project]) }
+ let(:ingress_mode) { :modsecurity_blocking }
+ let!(:ingress) { create(:clusters_applications_ingress, ingress_mode, cluster: cluster) }
+
+ context 'when cluster is disabled' do
+ let(:cluster) { create(:cluster, :disabled, projects: [project]) }
+
+ it 'gathers ingress data' do
+ expect(subject[:ingress_modsecurity_logging]).to eq(0)
+ expect(subject[:ingress_modsecurity_blocking]).to eq(0)
+ expect(subject[:ingress_modsecurity_disabled]).to eq(0)
+ expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
+ end
+ end
+
+ context 'when deployment is unsuccessful' do
+ let!(:deployment) { create(:deployment, :failed, environment: environment, project: project, cluster: cluster) }
+
+ it 'gathers ingress data' do
+ expect(subject[:ingress_modsecurity_logging]).to eq(0)
+ expect(subject[:ingress_modsecurity_blocking]).to eq(0)
+ expect(subject[:ingress_modsecurity_disabled]).to eq(0)
+ expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
+ end
+ end
+
+ context 'when deployment is successful' do
+ let!(:deployment) { create(:deployment, :success, environment: environment, project: project, cluster: cluster) }
+
+ context 'when modsecurity is in blocking mode' do
+ it 'gathers ingress data' do
+ expect(subject[:ingress_modsecurity_logging]).to eq(0)
+ expect(subject[:ingress_modsecurity_blocking]).to eq(1)
+ expect(subject[:ingress_modsecurity_disabled]).to eq(0)
+ expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
+ end
+ end
+
+ context 'when modsecurity is in logging mode' do
+ let(:ingress_mode) { :modsecurity_logging }
+
+ it 'gathers ingress data' do
+ expect(subject[:ingress_modsecurity_logging]).to eq(1)
+ expect(subject[:ingress_modsecurity_blocking]).to eq(0)
+ expect(subject[:ingress_modsecurity_disabled]).to eq(0)
+ expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
+ end
+ end
+
+ context 'when modsecurity is disabled' do
+ let(:ingress_mode) { :modsecurity_disabled }
+
+ it 'gathers ingress data' do
+ expect(subject[:ingress_modsecurity_logging]).to eq(0)
+ expect(subject[:ingress_modsecurity_blocking]).to eq(0)
+ expect(subject[:ingress_modsecurity_disabled]).to eq(1)
+ expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
+ end
+ end
+
+ context 'when modsecurity is not installed' do
+ let(:ingress_mode) { :modsecurity_not_installed }
+
+ it 'gathers ingress data' do
+ expect(subject[:ingress_modsecurity_logging]).to eq(0)
+ expect(subject[:ingress_modsecurity_blocking]).to eq(0)
+ expect(subject[:ingress_modsecurity_disabled]).to eq(0)
+ expect(subject[:ingress_modsecurity_not_installed]).to eq(1)
+ end
+ end
+
+ context 'with multiple projects' do
+ let(:environment_2) { create(:environment) }
+ let(:project_2) { environment_2.project }
+ let(:cluster_2) { create(:cluster, environment_scope: environment_scope, projects: [project_2]) }
+ let!(:ingress_2) { create(:clusters_applications_ingress, :modsecurity_logging, cluster: cluster_2) }
+ let!(:deployment_2) { create(:deployment, :success, environment: environment_2, project: project_2, cluster: cluster_2) }
+
+ it 'gathers non-duplicated ingress data' do
+ expect(subject[:ingress_modsecurity_logging]).to eq(1)
+ expect(subject[:ingress_modsecurity_blocking]).to eq(1)
+ expect(subject[:ingress_modsecurity_disabled]).to eq(0)
+ expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
+ end
+ end
+
+ context 'with multiple deployments' do
+ let!(:deployment_2) { create(:deployment, :success, environment: environment, project: project, cluster: cluster) }
+
+ it 'gathers non-duplicated ingress data' do
+ expect(subject[:ingress_modsecurity_logging]).to eq(0)
+ expect(subject[:ingress_modsecurity_blocking]).to eq(1)
+ expect(subject[:ingress_modsecurity_disabled]).to eq(0)
+ expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
+ end
+ end
+
+ context 'with multiple projects' do
+ let(:environment_2) { create(:environment) }
+ let(:project_2) { environment_2.project }
+ let!(:deployment_2) { create(:deployment, :success, environment: environment_2, project: project_2, cluster: cluster) }
+ let(:cluster) { create(:cluster, environment_scope: environment_scope, projects: [project, project_2]) }
+
+ it 'gathers ingress data' do
+ expect(subject[:ingress_modsecurity_logging]).to eq(0)
+ expect(subject[:ingress_modsecurity_blocking]).to eq(2)
+ expect(subject[:ingress_modsecurity_disabled]).to eq(0)
+ expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
+ end
+ end
+
+ context 'with multiple environments' do
+ let!(:environment_2) { create(:environment, project: project) }
+ let!(:deployment_2) { create(:deployment, :success, environment: environment_2, project: project, cluster: cluster) }
+
+ it 'gathers ingress data' do
+ expect(subject[:ingress_modsecurity_logging]).to eq(0)
+ expect(subject[:ingress_modsecurity_blocking]).to eq(2)
+ expect(subject[:ingress_modsecurity_disabled]).to eq(0)
+ expect(subject[:ingress_modsecurity_not_installed]).to eq(0)
+ end
+ end
end
end
diff --git a/spec/services/clusters/applications/ingress_modsecurity_usage_service_spec.rb b/spec/services/clusters/applications/ingress_modsecurity_usage_service_spec.rb
deleted file mode 100644
index d456284f76a..00000000000
--- a/spec/services/clusters/applications/ingress_modsecurity_usage_service_spec.rb
+++ /dev/null
@@ -1,196 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe Clusters::Applications::IngressModsecurityUsageService do
- describe '#execute' do
- ADO_MODSEC_KEY = Clusters::Applications::IngressModsecurityUsageService::ADO_MODSEC_KEY
-
- let(:project_with_ci_var) { create(:environment).project }
- let(:project_with_pipeline_var) { create(:environment).project }
-
- subject { described_class.new.execute }
-
- context 'with multiple projects' do
- let(:pipeline1) { create(:ci_pipeline, :with_job, project: project_with_pipeline_var) }
- let(:pipeline2) { create(:ci_pipeline, :with_job, project: project_with_ci_var) }
-
- let!(:deployment_with_pipeline_var) do
- create(
- :deployment,
- :success,
- environment: project_with_pipeline_var.environments.first,
- project: project_with_pipeline_var,
- deployable: pipeline1.builds.last
- )
- end
- let!(:deployment_with_project_var) do
- create(
- :deployment,
- :success,
- environment: project_with_ci_var.environments.first,
- project: project_with_ci_var,
- deployable: pipeline2.builds.last
- )
- end
-
- context 'mixed data' do
- let!(:ci_variable) { create(:ci_variable, project: project_with_ci_var, key: ADO_MODSEC_KEY, value: "On") }
- let!(:pipeline_variable) { create(:ci_pipeline_variable, pipeline: pipeline1, key: ADO_MODSEC_KEY, value: "Off") }
-
- it 'gathers variable data' do
- expect(subject[:ingress_modsecurity_blocking]).to eq(1)
- expect(subject[:ingress_modsecurity_disabled]).to eq(1)
- end
- end
-
- context 'blocking' do
- let(:modsec_values) { { key: ADO_MODSEC_KEY, value: "On" } }
-
- let!(:ci_variable) { create(:ci_variable, project: project_with_ci_var, **modsec_values) }
- let!(:pipeline_variable) { create(:ci_pipeline_variable, pipeline: pipeline1, **modsec_values) }
-
- it 'gathers variable data' do
- expect(subject[:ingress_modsecurity_blocking]).to eq(2)
- expect(subject[:ingress_modsecurity_disabled]).to eq(0)
- end
- end
-
- context 'disabled' do
- let(:modsec_values) { { key: ADO_MODSEC_KEY, value: "Off" } }
-
- let!(:ci_variable) { create(:ci_variable, project: project_with_ci_var, **modsec_values) }
- let!(:pipeline_variable) { create(:ci_pipeline_variable, pipeline: pipeline1, **modsec_values) }
-
- it 'gathers variable data' do
- expect(subject[:ingress_modsecurity_blocking]).to eq(0)
- expect(subject[:ingress_modsecurity_disabled]).to eq(2)
- end
- end
- end
-
- context 'when set as both ci and pipeline variables' do
- let(:modsec_values) { { key: ADO_MODSEC_KEY, value: "Off" } }
-
- let(:pipeline) { create(:ci_pipeline, :with_job, project: project_with_ci_var) }
- let!(:deployment) do
- create(
- :deployment,
- :success,
- environment: project_with_ci_var.environments.first,
- project: project_with_ci_var,
- deployable: pipeline.builds.last
- )
- end
-
- let!(:ci_variable) { create(:ci_variable, project: project_with_ci_var, **modsec_values) }
- let!(:pipeline_variable) { create(:ci_pipeline_variable, pipeline: pipeline, **modsec_values) }
-
- it 'wont double-count projects' do
- expect(subject[:ingress_modsecurity_blocking]).to eq(0)
- expect(subject[:ingress_modsecurity_disabled]).to eq(1)
- end
-
- it 'gives precedence to pipeline variable' do
- pipeline_variable.update(value: "On")
-
- expect(subject[:ingress_modsecurity_blocking]).to eq(1)
- expect(subject[:ingress_modsecurity_disabled]).to eq(0)
- end
- end
-
- context 'when a project has multiple environments' do
- let(:modsec_values) { { key: ADO_MODSEC_KEY, value: "On" } }
-
- let!(:env1) { project_with_pipeline_var.environments.first }
- let!(:env2) { create(:environment, project: project_with_pipeline_var) }
-
- let!(:pipeline_with_2_deployments) do
- create(:ci_pipeline, :with_job, project: project_with_ci_var).tap do |pip|
- pip.builds << build(:ci_build, pipeline: pip, project: project_with_pipeline_var)
- end
- end
-
- let!(:deployment1) do
- create(
- :deployment,
- :success,
- environment: env1,
- project: project_with_pipeline_var,
- deployable: pipeline_with_2_deployments.builds.last
- )
- end
- let!(:deployment2) do
- create(
- :deployment,
- :success,
- environment: env2,
- project: project_with_pipeline_var,
- deployable: pipeline_with_2_deployments.builds.last
- )
- end
-
- context 'when set as ci variable' do
- let!(:ci_variable) { create(:ci_variable, project: project_with_pipeline_var, **modsec_values) }
-
- it 'gathers variable data' do
- expect(subject[:ingress_modsecurity_blocking]).to eq(2)
- expect(subject[:ingress_modsecurity_disabled]).to eq(0)
- end
- end
-
- context 'when set as pipeline variable' do
- let!(:pipeline_variable) { create(:ci_pipeline_variable, pipeline: pipeline_with_2_deployments, **modsec_values) }
-
- it 'gathers variable data' do
- expect(subject[:ingress_modsecurity_blocking]).to eq(2)
- expect(subject[:ingress_modsecurity_disabled]).to eq(0)
- end
- end
- end
-
- context 'when an environment has multiple deployments' do
- let!(:env) { project_with_pipeline_var.environments.first }
-
- let!(:pipeline_first) do
- create(:ci_pipeline, :with_job, project: project_with_pipeline_var).tap do |pip|
- pip.builds << build(:ci_build, pipeline: pip, project: project_with_pipeline_var)
- end
- end
- let!(:pipeline_last) do
- create(:ci_pipeline, :with_job, project: project_with_pipeline_var).tap do |pip|
- pip.builds << build(:ci_build, pipeline: pip, project: project_with_pipeline_var)
- end
- end
-
- let!(:deployment_first) do
- create(
- :deployment,
- :success,
- environment: env,
- project: project_with_pipeline_var,
- deployable: pipeline_first.builds.last
- )
- end
- let!(:deployment_last) do
- create(
- :deployment,
- :success,
- environment: env,
- project: project_with_pipeline_var,
- deployable: pipeline_last.builds.last
- )
- end
-
- context 'when set as pipeline variable' do
- let!(:first_pipeline_variable) { create(:ci_pipeline_variable, pipeline: pipeline_first, key: ADO_MODSEC_KEY, value: "On") }
- let!(:last_pipeline_variable) { create(:ci_pipeline_variable, pipeline: pipeline_last, key: ADO_MODSEC_KEY, value: "Off") }
-
- it 'gives precedence to latest deployment' do
- expect(subject[:ingress_modsecurity_blocking]).to eq(0)
- expect(subject[:ingress_modsecurity_disabled]).to eq(1)
- end
- end
- end
- end
-end