97 lines
2.7 KiB
Ruby
97 lines
2.7 KiB
Ruby
|
# 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
|