Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/services/metrics')
-rw-r--r--app/services/metrics/dashboard/base_service.rb22
-rw-r--r--app/services/metrics/dashboard/clone_dashboard_service.rb66
-rw-r--r--app/services/metrics/dashboard/cluster_dashboard_service.rb40
-rw-r--r--app/services/metrics/dashboard/cluster_metrics_embed_service.rb37
-rw-r--r--app/services/metrics/dashboard/custom_dashboard_service.rb5
-rw-r--r--app/services/metrics/dashboard/gitlab_alert_embed_service.rb2
-rw-r--r--app/services/metrics/dashboard/grafana_metric_embed_service.rb6
-rw-r--r--app/services/metrics/dashboard/pod_dashboard_service.rb9
-rw-r--r--app/services/metrics/dashboard/predefined_dashboard_service.rb15
-rw-r--r--app/services/metrics/dashboard/self_monitoring_dashboard_service.rb15
-rw-r--r--app/services/metrics/dashboard/system_dashboard_service.rb15
-rw-r--r--app/services/metrics/dashboard/transient_embed_service.rb4
12 files changed, 196 insertions, 40 deletions
diff --git a/app/services/metrics/dashboard/base_service.rb b/app/services/metrics/dashboard/base_service.rb
index c2a0f22e73e..5fa127d64b2 100644
--- a/app/services/metrics/dashboard/base_service.rb
+++ b/app/services/metrics/dashboard/base_service.rb
@@ -10,7 +10,8 @@ module Metrics
STAGES = ::Gitlab::Metrics::Dashboard::Stages
SEQUENCE = [
STAGES::CommonMetricsInserter,
- STAGES::EndpointInserter,
+ STAGES::MetricEndpointInserter,
+ STAGES::VariableEndpointInserter,
STAGES::PanelIdsInserter,
STAGES::Sorter,
STAGES::AlertsInserter,
@@ -36,6 +37,14 @@ module Metrics
Gitlab::Metrics::Dashboard::Cache.fetch(cache_key) { get_raw_dashboard }
end
+ # Should return true if this dashboard service is for an out-of-the-box
+ # dashboard.
+ # This method is overridden in app/services/metrics/dashboard/predefined_dashboard_service.rb.
+ # @return Boolean
+ def self.out_of_the_box_dashboard?
+ false
+ end
+
private
# Determines whether users should be able to view
@@ -83,6 +92,17 @@ module Metrics
params[:dashboard_path]
end
+ def load_yaml(data)
+ ::Gitlab::Config::Loader::Yaml.new(data).load_raw!
+ rescue Gitlab::Config::Loader::Yaml::NotHashError
+ # Raise more informative error in app/models/performance_monitoring/prometheus_dashboard.rb.
+ {}
+ rescue Gitlab::Config::Loader::Yaml::DataTooLargeError => exception
+ raise Gitlab::Metrics::Dashboard::Errors::LayoutError, exception.message
+ rescue Gitlab::Config::Loader::FormatError
+ raise Gitlab::Metrics::Dashboard::Errors::LayoutError, _('Invalid yaml')
+ end
+
# @return [Hash] an unmodified dashboard
def get_raw_dashboard
raise NotImplementedError
diff --git a/app/services/metrics/dashboard/clone_dashboard_service.rb b/app/services/metrics/dashboard/clone_dashboard_service.rb
index 3ca25b3bd9b..a6bece391f2 100644
--- a/app/services/metrics/dashboard/clone_dashboard_service.rb
+++ b/app/services/metrics/dashboard/clone_dashboard_service.rb
@@ -6,30 +6,33 @@ module Metrics
module Dashboard
class CloneDashboardService < ::BaseService
include Stepable
+ include Gitlab::Utils::StrongMemoize
ALLOWED_FILE_TYPE = '.yml'
USER_DASHBOARDS_DIR = ::Metrics::Dashboard::CustomDashboardService::DASHBOARD_ROOT
+ SEQUENCES = {
+ ::Metrics::Dashboard::SystemDashboardService::DASHBOARD_PATH => [
+ ::Gitlab::Metrics::Dashboard::Stages::CommonMetricsInserter,
+ ::Gitlab::Metrics::Dashboard::Stages::CustomMetricsInserter,
+ ::Gitlab::Metrics::Dashboard::Stages::Sorter
+ ].freeze,
+
+ ::Metrics::Dashboard::SelfMonitoringDashboardService::DASHBOARD_PATH => [
+ ::Gitlab::Metrics::Dashboard::Stages::CustomMetricsInserter
+ ].freeze,
+
+ ::Metrics::Dashboard::ClusterDashboardService::DASHBOARD_PATH => [
+ ::Gitlab::Metrics::Dashboard::Stages::CommonMetricsInserter,
+ ::Gitlab::Metrics::Dashboard::Stages::Sorter
+ ].freeze
+ }.freeze
steps :check_push_authorized,
- :check_branch_name,
- :check_file_type,
- :check_dashboard_template,
- :create_file,
- :refresh_repository_method_caches
-
- class << self
- def allowed_dashboard_templates
- @allowed_dashboard_templates ||= Set[::Metrics::Dashboard::SystemDashboardService::DASHBOARD_PATH].freeze
- end
-
- def sequences
- @sequences ||= {
- ::Metrics::Dashboard::SystemDashboardService::DASHBOARD_PATH => [::Gitlab::Metrics::Dashboard::Stages::CommonMetricsInserter,
- ::Gitlab::Metrics::Dashboard::Stages::CustomMetricsInserter,
- ::Gitlab::Metrics::Dashboard::Stages::Sorter].freeze
- }.freeze
- end
- end
+ :check_branch_name,
+ :check_file_type,
+ :check_dashboard_template,
+ :create_file,
+ :refresh_repository_method_caches
def execute
execute_steps
@@ -56,8 +59,12 @@ module Metrics
success(result)
end
+ # Only allow out of the box metrics dashboards to be cloned. This can be
+ # changed to allow cloning of any metrics dashboard, if desired.
+ # However, only metrics dashboards should be allowed. If any file is
+ # allowed to be cloned, this will become a security risk.
def check_dashboard_template(result)
- return error(_('Not found.'), :not_found) unless self.class.allowed_dashboard_templates.include?(params[:dashboard])
+ return error(_('Not found.'), :not_found) unless dashboard_service&.out_of_the_box_dashboard?
success(result)
end
@@ -78,6 +85,12 @@ module Metrics
success(result.merge(http_status: :created, dashboard: dashboard_details))
end
+ def dashboard_service
+ strong_memoize(:dashboard_service) do
+ Gitlab::Metrics::Dashboard::ServiceSelector.call(dashboard_service_options)
+ end
+ end
+
def dashboard_attrs
{
commit_message: params[:commit_message],
@@ -149,14 +162,19 @@ module Metrics
end
def raw_dashboard
- YAML.safe_load(File.read(Rails.root.join(dashboard_template)))
+ dashboard_service.new(project, current_user, dashboard_service_options).raw_dashboard
+ end
+
+ def dashboard_service_options
+ {
+ embedded: false,
+ dashboard_path: dashboard_template
+ }
end
def sequence
- self.class.sequences[dashboard_template]
+ SEQUENCES[dashboard_template] || []
end
end
end
end
-
-Metrics::Dashboard::CloneDashboardService.prepend_if_ee('EE::Metrics::Dashboard::CloneDashboardService')
diff --git a/app/services/metrics/dashboard/cluster_dashboard_service.rb b/app/services/metrics/dashboard/cluster_dashboard_service.rb
new file mode 100644
index 00000000000..bfd5abf1126
--- /dev/null
+++ b/app/services/metrics/dashboard/cluster_dashboard_service.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+# Fetches the system metrics dashboard and formats the output.
+# Use Gitlab::Metrics::Dashboard::Finder to retrive dashboards.
+module Metrics
+ module Dashboard
+ class ClusterDashboardService < ::Metrics::Dashboard::PredefinedDashboardService
+ DASHBOARD_PATH = 'config/prometheus/cluster_metrics.yml'
+ DASHBOARD_NAME = 'Cluster'
+
+ # SHA256 hash of dashboard content
+ DASHBOARD_VERSION = '9349afc1d96329c08ab478ea0b77db94ee5cc2549b8c754fba67a7f424666b22'
+
+ SEQUENCE = [
+ STAGES::ClusterEndpointInserter,
+ STAGES::PanelIdsInserter,
+ STAGES::Sorter
+ ].freeze
+
+ class << self
+ def valid_params?(params)
+ # support selecting this service by cluster id via .find
+ # Use super to support selecting this service by dashboard_path via .find_raw
+ (params[:cluster].present? && params[:embedded] != 'true') || super
+ end
+ end
+
+ # Permissions are handled at the controller level
+ def allowed?
+ true
+ end
+
+ private
+
+ def dashboard_version
+ DASHBOARD_VERSION
+ end
+ end
+ end
+end
diff --git a/app/services/metrics/dashboard/cluster_metrics_embed_service.rb b/app/services/metrics/dashboard/cluster_metrics_embed_service.rb
new file mode 100644
index 00000000000..6fb39ed3004
--- /dev/null
+++ b/app/services/metrics/dashboard/cluster_metrics_embed_service.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+#
+module Metrics
+ module Dashboard
+ class ClusterMetricsEmbedService < Metrics::Dashboard::DynamicEmbedService
+ class << self
+ def valid_params?(params)
+ [
+ params[:cluster],
+ embedded?(params[:embedded]),
+ params[:group].present?,
+ params[:title].present?,
+ params[:y_label].present?
+ ].all?
+ end
+ end
+
+ private
+
+ # Permissions are handled at the controller level
+ def allowed?
+ true
+ end
+
+ def dashboard_path
+ ::Metrics::Dashboard::ClusterDashboardService::DASHBOARD_PATH
+ end
+
+ def sequence
+ [
+ STAGES::ClusterEndpointInserter,
+ STAGES::PanelIdsInserter
+ ]
+ end
+ end
+ end
+end
diff --git a/app/services/metrics/dashboard/custom_dashboard_service.rb b/app/services/metrics/dashboard/custom_dashboard_service.rb
index 77173813a4f..741738cc3af 100644
--- a/app/services/metrics/dashboard/custom_dashboard_service.rb
+++ b/app/services/metrics/dashboard/custom_dashboard_service.rb
@@ -21,7 +21,8 @@ module Metrics
path: filepath,
display_name: name_for_path(filepath),
default: false,
- system_dashboard: false
+ system_dashboard: false,
+ out_of_the_box_dashboard: out_of_the_box_dashboard?
}
end
end
@@ -42,7 +43,7 @@ module Metrics
def get_raw_dashboard
yml = self.class.file_finder(project).read(dashboard_path)
- YAML.safe_load(yml)
+ load_yaml(yml)
end
def cache_key
diff --git a/app/services/metrics/dashboard/gitlab_alert_embed_service.rb b/app/services/metrics/dashboard/gitlab_alert_embed_service.rb
index 38e89d392ad..08d65413e1d 100644
--- a/app/services/metrics/dashboard/gitlab_alert_embed_service.rb
+++ b/app/services/metrics/dashboard/gitlab_alert_embed_service.rb
@@ -11,7 +11,7 @@ module Metrics
include Gitlab::Utils::StrongMemoize
SEQUENCE = [
- STAGES::EndpointInserter,
+ STAGES::MetricEndpointInserter,
STAGES::PanelIdsInserter
].freeze
diff --git a/app/services/metrics/dashboard/grafana_metric_embed_service.rb b/app/services/metrics/dashboard/grafana_metric_embed_service.rb
index d9ce2c5e905..8e72a185406 100644
--- a/app/services/metrics/dashboard/grafana_metric_embed_service.rb
+++ b/app/services/metrics/dashboard/grafana_metric_embed_service.rb
@@ -80,7 +80,7 @@ module Metrics
def fetch_dashboard
uid = GrafanaUidParser.new(grafana_url, project).parse
- raise DashboardProcessingError.new('Dashboard uid not found') unless uid
+ raise DashboardProcessingError.new(_('Dashboard uid not found')) unless uid
response = client.get_dashboard(uid: uid)
@@ -89,7 +89,7 @@ module Metrics
def fetch_datasource(dashboard)
name = DatasourceNameParser.new(grafana_url, dashboard).parse
- raise DashboardProcessingError.new('Datasource name not found') unless name
+ raise DashboardProcessingError.new(_('Datasource name not found')) unless name
response = client.get_datasource(name: name)
@@ -115,7 +115,7 @@ module Metrics
def parse_json(json)
Gitlab::Json.parse(json, symbolize_names: true)
rescue JSON::ParserError
- raise DashboardProcessingError.new('Grafana response contains invalid json')
+ raise DashboardProcessingError.new(_('Grafana response contains invalid json'))
end
end
diff --git a/app/services/metrics/dashboard/pod_dashboard_service.rb b/app/services/metrics/dashboard/pod_dashboard_service.rb
index 16b87d2d587..8699189deac 100644
--- a/app/services/metrics/dashboard/pod_dashboard_service.rb
+++ b/app/services/metrics/dashboard/pod_dashboard_service.rb
@@ -5,6 +5,15 @@ module Metrics
class PodDashboardService < ::Metrics::Dashboard::PredefinedDashboardService
DASHBOARD_PATH = 'config/prometheus/pod_metrics.yml'
DASHBOARD_NAME = 'Pod Health'
+
+ # SHA256 hash of dashboard content
+ DASHBOARD_VERSION = 'f12f641d2575d5dcb69e2c633ff5231dbd879ad35020567d8fc4e1090bfdb4b4'
+
+ private
+
+ def dashboard_version
+ DASHBOARD_VERSION
+ end
end
end
end
diff --git a/app/services/metrics/dashboard/predefined_dashboard_service.rb b/app/services/metrics/dashboard/predefined_dashboard_service.rb
index f454df63773..c21083475f0 100644
--- a/app/services/metrics/dashboard/predefined_dashboard_service.rb
+++ b/app/services/metrics/dashboard/predefined_dashboard_service.rb
@@ -10,7 +10,8 @@ module Metrics
DASHBOARD_NAME = nil
SEQUENCE = [
- STAGES::EndpointInserter,
+ STAGES::MetricEndpointInserter,
+ STAGES::VariableEndpointInserter,
STAGES::PanelIdsInserter,
STAGES::Sorter
].freeze
@@ -23,12 +24,20 @@ module Metrics
def matching_dashboard?(filepath)
filepath == self::DASHBOARD_PATH
end
+
+ def out_of_the_box_dashboard?
+ true
+ end
end
private
+ def dashboard_version
+ raise NotImplementedError
+ end
+
def cache_key
- "metrics_dashboard_#{dashboard_path}"
+ "metrics_dashboard_#{dashboard_path}_#{dashboard_version}"
end
def dashboard_path
@@ -39,7 +48,7 @@ module Metrics
def get_raw_dashboard
yml = File.read(Rails.root.join(dashboard_path))
- YAML.safe_load(yml)
+ load_yaml(yml)
end
def sequence
diff --git a/app/services/metrics/dashboard/self_monitoring_dashboard_service.rb b/app/services/metrics/dashboard/self_monitoring_dashboard_service.rb
index 8599c23c206..f1f5cd7d77e 100644
--- a/app/services/metrics/dashboard/self_monitoring_dashboard_service.rb
+++ b/app/services/metrics/dashboard/self_monitoring_dashboard_service.rb
@@ -8,9 +8,13 @@ module Metrics
DASHBOARD_PATH = 'config/prometheus/self_monitoring_default.yml'
DASHBOARD_NAME = N_('Default dashboard')
+ # SHA256 hash of dashboard content
+ DASHBOARD_VERSION = '1dff3e3cb76e73c8e368823c98b34c61aec0d141978450dea195a3b3dc2415d6'
+
SEQUENCE = [
STAGES::CustomMetricsInserter,
- STAGES::EndpointInserter,
+ STAGES::MetricEndpointInserter,
+ STAGES::VariableEndpointInserter,
STAGES::PanelIdsInserter,
STAGES::Sorter
].freeze
@@ -25,7 +29,8 @@ module Metrics
path: DASHBOARD_PATH,
display_name: _(DASHBOARD_NAME),
default: true,
- system_dashboard: false
+ system_dashboard: false,
+ out_of_the_box_dashboard: out_of_the_box_dashboard?
}]
end
@@ -33,6 +38,12 @@ module Metrics
params[:dashboard_path].nil? && params[:environment]&.project&.self_monitoring?
end
end
+
+ private
+
+ def dashboard_version
+ DASHBOARD_VERSION
+ end
end
end
end
diff --git a/app/services/metrics/dashboard/system_dashboard_service.rb b/app/services/metrics/dashboard/system_dashboard_service.rb
index db5599b4def..5c3562b8ca0 100644
--- a/app/services/metrics/dashboard/system_dashboard_service.rb
+++ b/app/services/metrics/dashboard/system_dashboard_service.rb
@@ -8,11 +8,15 @@ module Metrics
DASHBOARD_PATH = 'config/prometheus/common_metrics.yml'
DASHBOARD_NAME = N_('Default dashboard')
+ # SHA256 hash of dashboard content
+ DASHBOARD_VERSION = '4685fe386c25b1a786b3be18f79bb2ee9828019003e003816284cdb634fa3e13'
+
SEQUENCE = [
STAGES::CommonMetricsInserter,
STAGES::CustomMetricsInserter,
STAGES::CustomMetricsDetailsInserter,
- STAGES::EndpointInserter,
+ STAGES::MetricEndpointInserter,
+ STAGES::VariableEndpointInserter,
STAGES::PanelIdsInserter,
STAGES::Sorter,
STAGES::AlertsInserter
@@ -24,10 +28,17 @@ module Metrics
path: DASHBOARD_PATH,
display_name: _(DASHBOARD_NAME),
default: true,
- system_dashboard: true
+ system_dashboard: true,
+ out_of_the_box_dashboard: out_of_the_box_dashboard?
}]
end
end
+
+ private
+
+ def dashboard_version
+ DASHBOARD_VERSION
+ end
end
end
end
diff --git a/app/services/metrics/dashboard/transient_embed_service.rb b/app/services/metrics/dashboard/transient_embed_service.rb
index cb6ca215447..0a9c4bc7b86 100644
--- a/app/services/metrics/dashboard/transient_embed_service.rb
+++ b/app/services/metrics/dashboard/transient_embed_service.rb
@@ -30,7 +30,7 @@ module Metrics
override :sequence
def sequence
- [STAGES::EndpointInserter]
+ [STAGES::MetricEndpointInserter]
end
override :identifiers
@@ -39,7 +39,7 @@ module Metrics
end
def invalid_embed_json!(message)
- raise DashboardProcessingError.new("Parsing error for param :embed_json. #{message}")
+ raise DashboardProcessingError.new(_("Parsing error for param :embed_json. %{message}") % { message: message })
end
end
end