diff options
Diffstat (limited to 'lib/gitlab/metrics/dashboard/stages')
-rw-r--r-- | lib/gitlab/metrics/dashboard/stages/base_stage.rb | 8 | ||||
-rw-r--r-- | lib/gitlab/metrics/dashboard/stages/cluster_endpoint_inserter.rb | 83 | ||||
-rw-r--r-- | lib/gitlab/metrics/dashboard/stages/metric_endpoint_inserter.rb (renamed from lib/gitlab/metrics/dashboard/stages/endpoint_inserter.rb) | 10 | ||||
-rw-r--r-- | lib/gitlab/metrics/dashboard/stages/sorter.rb | 4 | ||||
-rw-r--r-- | lib/gitlab/metrics/dashboard/stages/url_validator.rb | 43 | ||||
-rw-r--r-- | lib/gitlab/metrics/dashboard/stages/variable_endpoint_inserter.rb | 34 |
6 files changed, 175 insertions, 7 deletions
diff --git a/lib/gitlab/metrics/dashboard/stages/base_stage.rb b/lib/gitlab/metrics/dashboard/stages/base_stage.rb index 622d5aa8cdb..ee2d36621b4 100644 --- a/lib/gitlab/metrics/dashboard/stages/base_stage.rb +++ b/lib/gitlab/metrics/dashboard/stages/base_stage.rb @@ -48,6 +48,14 @@ module Gitlab end end + def for_variables + return unless dashboard.dig(:templating, :variables).is_a?(Hash) + + dashboard.dig(:templating, :variables).each do |variable_name, variable| + yield variable_name, variable + end + end + def for_panel_groups dashboard[:panel_groups].each do |panel_group| yield panel_group diff --git a/lib/gitlab/metrics/dashboard/stages/cluster_endpoint_inserter.rb b/lib/gitlab/metrics/dashboard/stages/cluster_endpoint_inserter.rb new file mode 100644 index 00000000000..a12082b704c --- /dev/null +++ b/lib/gitlab/metrics/dashboard/stages/cluster_endpoint_inserter.rb @@ -0,0 +1,83 @@ +# frozen_string_literal: true + +module Gitlab + module Metrics + module Dashboard + module Stages + class ClusterEndpointInserter < BaseStage + def transform! + verify_params + + for_metrics do |metric| + metric[:prometheus_endpoint_path] = endpoint_for_metric(metric) + end + end + + private + + def admin_url(metric) + Gitlab::Routing.url_helpers.prometheus_api_admin_cluster_path( + params[:cluster], + proxy_path: query_type(metric), + query: query_for_metric(metric) + ) + end + + def endpoint_for_metric(metric) + case params[:cluster_type] + when :admin + admin_url(metric) + when :group + error!(_('Group is required when cluster_type is :group')) unless params[:group] + group_url(metric) + when :project + error!(_('Project is required when cluster_type is :project')) unless project + project_url(metric) + else + error!(_('Unrecognized cluster type')) + end + end + + def error!(message) + raise Errors::DashboardProcessingError.new(message) + end + + def group_url(metric) + Gitlab::Routing.url_helpers.prometheus_api_group_cluster_path( + params[:group], + params[:cluster], + proxy_path: query_type(metric), + query: query_for_metric(metric) + ) + end + + def project_url(metric) + Gitlab::Routing.url_helpers.prometheus_api_project_cluster_path( + project, + params[:cluster], + proxy_path: query_type(metric), + query: query_for_metric(metric) + ) + end + + def query_type(metric) + metric[:query] ? :query : :query_range + end + + def query_for_metric(metric) + query = metric[query_type(metric)] + + raise Errors::MissingQueryError.new('Each "metric" must define one of :query or :query_range') unless query + + query + end + + def verify_params + raise Errors::DashboardProcessingError.new(_('Cluster is required for Stages::ClusterEndpointInserter')) unless params[:cluster] + raise Errors::DashboardProcessingError.new(_('Cluster type must be specificed for Stages::ClusterEndpointInserter')) unless params[:cluster_type] + end + end + end + end + end +end diff --git a/lib/gitlab/metrics/dashboard/stages/endpoint_inserter.rb b/lib/gitlab/metrics/dashboard/stages/metric_endpoint_inserter.rb index e085f551952..c48a7ff25a5 100644 --- a/lib/gitlab/metrics/dashboard/stages/endpoint_inserter.rb +++ b/lib/gitlab/metrics/dashboard/stages/metric_endpoint_inserter.rb @@ -4,9 +4,9 @@ module Gitlab module Metrics module Dashboard module Stages - class EndpointInserter < BaseStage + class MetricEndpointInserter < BaseStage def transform! - raise Errors::DashboardProcessingError.new('Environment is required for Stages::EndpointInserter') unless params[:environment] + raise Errors::DashboardProcessingError.new(_('Environment is required for Stages::MetricEndpointInserter')) unless params[:environment] for_metrics do |metric| metric[:prometheus_endpoint_path] = endpoint_for_metric(metric) @@ -33,7 +33,11 @@ module Gitlab end def query_type(metric) - metric[:query] ? :query : :query_range + if metric[:query] + ::Prometheus::ProxyService::PROMETHEUS_QUERY_API.to_sym + else + ::Prometheus::ProxyService::PROMETHEUS_QUERY_RANGE_API.to_sym + end end def query_for_metric(metric) diff --git a/lib/gitlab/metrics/dashboard/stages/sorter.rb b/lib/gitlab/metrics/dashboard/stages/sorter.rb index ba5aa78059c..882211e1441 100644 --- a/lib/gitlab/metrics/dashboard/stages/sorter.rb +++ b/lib/gitlab/metrics/dashboard/stages/sorter.rb @@ -16,7 +16,7 @@ module Gitlab # Sorts the groups in the dashboard by the :priority key def sort_groups! - dashboard[:panel_groups] = dashboard[:panel_groups].sort_by { |group| -group[:priority].to_i } + dashboard[:panel_groups] = Gitlab::Utils.stable_sort_by(dashboard[:panel_groups]) { |group| -group[:priority].to_i } end # Sorts the panels in the dashboard by the :weight key @@ -24,7 +24,7 @@ module Gitlab dashboard[:panel_groups].each do |group| missing_panels! unless group[:panels].is_a? Array - group[:panels] = group[:panels].sort_by { |panel| -panel[:weight].to_i } + group[:panels] = Gitlab::Utils.stable_sort_by(group[:panels]) { |panel| -panel[:weight].to_i } end end end diff --git a/lib/gitlab/metrics/dashboard/stages/url_validator.rb b/lib/gitlab/metrics/dashboard/stages/url_validator.rb index ff36f7b605e..9e2bb0d1a70 100644 --- a/lib/gitlab/metrics/dashboard/stages/url_validator.rb +++ b/lib/gitlab/metrics/dashboard/stages/url_validator.rb @@ -6,8 +6,47 @@ module Gitlab module Stages class UrlValidator < BaseStage def transform! - dashboard[:links]&.each do |link| - Gitlab::UrlBlocker.validate!(link[:url]) + validate_dashboard_links(dashboard) + + validate_chart_links(dashboard) + end + + private + + def blocker_args + { + schemes: %w(http https), + ports: [], + allow_localhost: allow_setting_local_requests?, + allow_local_network: allow_setting_local_requests?, + ascii_only: false, + enforce_user: false, + enforce_sanitization: false, + dns_rebind_protection: true + } + end + + def allow_setting_local_requests? + Gitlab::CurrentSettings.allow_local_requests_from_web_hooks_and_services? + end + + def validate_dashboard_links(dashboard) + validate_links(dashboard[:links]) + end + + def validate_chart_links(dashboard) + dashboard[:panel_groups].each do |panel_group| + panel_group[:panels].each do |panel| + validate_links(panel[:links]) + end + end + end + + def validate_links(links) + links&.each do |link| + next unless link.is_a? Hash + + Gitlab::UrlBlocker.validate!(link[:url], blocker_args) rescue Gitlab::UrlBlocker::BlockedUrlError link[:url] = '' end diff --git a/lib/gitlab/metrics/dashboard/stages/variable_endpoint_inserter.rb b/lib/gitlab/metrics/dashboard/stages/variable_endpoint_inserter.rb new file mode 100644 index 00000000000..20e7fe477e5 --- /dev/null +++ b/lib/gitlab/metrics/dashboard/stages/variable_endpoint_inserter.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module Gitlab + module Metrics + module Dashboard + module Stages + class VariableEndpointInserter < BaseStage + VARIABLE_TYPE_METRIC_LABEL_VALUES = 'metric_label_values' + + def transform! + raise Errors::DashboardProcessingError.new(_('Environment is required for Stages::VariableEndpointInserter')) unless params[:environment] + + for_variables do |variable_name, variable| + if variable.is_a?(Hash) && variable[:type] == VARIABLE_TYPE_METRIC_LABEL_VALUES + variable[:options][:prometheus_endpoint_path] = endpoint_for_variable(variable.dig(:options, :series_selector)) + end + end + end + + private + + def endpoint_for_variable(series_selector) + Gitlab::Routing.url_helpers.prometheus_api_project_environment_path( + project, + params[:environment], + proxy_path: ::Prometheus::ProxyService::PROMETHEUS_SERIES_API, + match: Array(series_selector) + ) + end + end + end + end + end +end |