summaryrefslogtreecommitdiff
path: root/lib/grafana/validator.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/grafana/validator.rb')
-rw-r--r--lib/grafana/validator.rb96
1 files changed, 96 insertions, 0 deletions
diff --git a/lib/grafana/validator.rb b/lib/grafana/validator.rb
new file mode 100644
index 00000000000..760263f7ec9
--- /dev/null
+++ b/lib/grafana/validator.rb
@@ -0,0 +1,96 @@
+# frozen_string_literal: true
+
+# Performs checks on whether resources from Grafana can be handled
+# We have certain restrictions on which formats we accept.
+# Some are technical requirements, others are simplifications.
+module Grafana
+ class Validator
+ Error = Class.new(StandardError)
+
+ attr_reader :grafana_dashboard, :datasource, :panel, :query_params
+
+ UNSUPPORTED_GRAFANA_GLOBAL_VARS = %w(
+ $__interval_ms
+ $__timeFilter
+ $__name
+ $timeFilter
+ $interval
+ ).freeze
+
+ def initialize(grafana_dashboard, datasource, panel, query_params)
+ @grafana_dashboard = grafana_dashboard
+ @datasource = datasource
+ @panel = panel
+ @query_params = query_params
+ end
+
+ def validate!
+ validate_query_params!
+ validate_panel_type!
+ validate_variable_definitions!
+ validate_global_variables!
+ validate_datasource! if datasource
+ end
+
+ def valid?
+ validate!
+
+ true
+ rescue ::Grafana::Validator::Error
+ false
+ end
+
+ private
+
+ # See defaults in Banzai::Filter::InlineGrafanaMetricsFilter.
+ def validate_query_params!
+ return if [:from, :to].all? { |param| query_params.include?(param) }
+
+ raise_error 'Grafana query parameters must include from and to.'
+ end
+
+ # We may choose to support other panel types in future.
+ def validate_panel_type!
+ return if panel && panel[:type] == 'graph' && panel[:lines]
+
+ raise_error 'Panel type must be a line graph.'
+ end
+
+ # We must require variable definitions to create valid prometheus queries.
+ def validate_variable_definitions!
+ return unless grafana_dashboard[:dashboard][:templating]
+
+ return if grafana_dashboard[:dashboard][:templating][:list].all? do |variable|
+ query_params[:"var-#{variable[:name]}"].present?
+ end
+
+ raise_error 'All Grafana variables must be defined in the query parameters.'
+ end
+
+ # We may choose to support further Grafana variables in future.
+ def validate_global_variables!
+ return unless panel_contains_unsupported_vars?
+
+ raise_error "Prometheus must not include #{UNSUPPORTED_GRAFANA_GLOBAL_VARS}"
+ end
+
+ # We may choose to support additional datasources in future.
+ def validate_datasource!
+ return if datasource[:access] == 'proxy' && datasource[:type] == 'prometheus'
+
+ raise_error 'Only Prometheus datasources with proxy access in Grafana are supported.'
+ end
+
+ def panel_contains_unsupported_vars?
+ panel[:targets].any? do |target|
+ UNSUPPORTED_GRAFANA_GLOBAL_VARS.any? do |variable|
+ target[:expr].include?(variable)
+ end
+ end
+ end
+
+ def raise_error(message)
+ raise Validator::Error, message
+ end
+ end
+end