diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2019-12-05 00:07:31 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2019-12-05 00:07:31 +0300 |
commit | 71221554dd9ddf30f73035c89f78164e001aa96d (patch) | |
tree | c56e0b2fc3dd16602183b78cb3f68aed211c5e77 /app/services/clusters | |
parent | b41cd8cb92d53454b2b160ba922d33801933a9cf (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/services/clusters')
-rw-r--r-- | app/services/clusters/applications/ingress_modsecurity_usage_service.rb | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/app/services/clusters/applications/ingress_modsecurity_usage_service.rb b/app/services/clusters/applications/ingress_modsecurity_usage_service.rb new file mode 100644 index 00000000000..4aac8bb3cbd --- /dev/null +++ b/app/services/clusters/applications/ingress_modsecurity_usage_service.rb @@ -0,0 +1,69 @@ +# 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 |