Commit 11be9385 authored by rpereira2's avatar rpereira2

Add prometheus_endpoint_path for variables

- The metric_label_values type of variable needs the results of a
Prometheus query.

- Similar to how we add a prometheus_endpoint_path key for panels in the
dashboard, add it for variables of type metric_label_values.
parent 6a0e0980
......@@ -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,
......
......@@ -11,7 +11,7 @@ module Metrics
include Gitlab::Utils::StrongMemoize
SEQUENCE = [
STAGES::EndpointInserter,
STAGES::MetricEndpointInserter,
STAGES::PanelIdsInserter
].freeze
......
......@@ -10,7 +10,8 @@ module Metrics
DASHBOARD_NAME = nil
SEQUENCE = [
STAGES::EndpointInserter,
STAGES::MetricEndpointInserter,
STAGES::VariableEndpointInserter,
STAGES::PanelIdsInserter,
STAGES::Sorter
].freeze
......
......@@ -10,7 +10,8 @@ module Metrics
SEQUENCE = [
STAGES::CustomMetricsInserter,
STAGES::EndpointInserter,
STAGES::MetricEndpointInserter,
STAGES::VariableEndpointInserter,
STAGES::PanelIdsInserter,
STAGES::Sorter
].freeze
......
......@@ -12,7 +12,8 @@ module Metrics
STAGES::CommonMetricsInserter,
STAGES::CustomMetricsInserter,
STAGES::CustomMetricsDetailsInserter,
STAGES::EndpointInserter,
STAGES::MetricEndpointInserter,
STAGES::VariableEndpointInserter,
STAGES::PanelIdsInserter,
STAGES::Sorter,
STAGES::AlertsInserter
......
......@@ -30,7 +30,7 @@ module Metrics
override :sequence
def sequence
[STAGES::EndpointInserter]
[STAGES::MetricEndpointInserter]
end
override :identifiers
......
......@@ -22,16 +22,20 @@ module Prometheus
attr_accessor :proxyable, :method, :path, :params
PROMETHEUS_QUERY_API = 'query'
PROMETHEUS_QUERY_RANGE_API = 'query_range'
PROMETHEUS_SERIES_API = 'series'
PROXY_SUPPORT = {
'query' => {
PROMETHEUS_QUERY_API => {
method: ['GET'],
params: %w(query time timeout)
},
'query_range' => {
PROMETHEUS_QUERY_RANGE_API => {
method: ['GET'],
params: %w(query start end step timeout)
},
'series' => {
PROMETHEUS_SERIES_API => {
method: %w(GET),
params: %w(match start end)
}
......
......@@ -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
......
......@@ -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)
......
# 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
......@@ -8555,6 +8555,9 @@ msgstr ""
msgid "Environment does not have deployments"
msgstr ""
msgid "Environment is required for Stages::VariableEndpointInserter"
msgstr ""
msgid "Environment scope"
msgstr ""
......
......@@ -24,6 +24,12 @@ templating:
- value: 'value_option_2'
text: 'Option 2'
default: true
metric_label_values_variable:
label: 'Variable 3'
type: metric_label_values
options:
series_selector: 'backend:haproxy_backend_availability:ratio{env="{{env}}"}'
label: 'backend'
panel_groups:
- group: Group A
priority: 1
......
{
"type": "object",
"required": [
"type", "options"
],
"properties": {
"type": { "enum": "metric_label_values" },
"label": { "type": "string" },
"options": { "$ref": "metric_label_values_variable_options.json" }
},
"additionalProperties": false
}
{
"type": "object",
"required": [
"series_selector", "label", "prometheus_endpoint_path"
],
"properties": {
"series_selector": { "type": "string" },
"label": { "type": "string" },
"prometheus_endpoint_path": { "type": "string" }
},
"additionalProperties": false
}
......@@ -9,7 +9,8 @@
"type": "array",
"items": { "type": "string" }
},
{ "$ref": "custom_variable_full_syntax.json" }
{ "$ref": "custom_variable_full_syntax.json" },
{ "$ref": "metric_label_values_variable_full_syntax.json" }
]
}
},
......
......@@ -13,7 +13,7 @@ describe Gitlab::Metrics::Dashboard::Processor do
Gitlab::Metrics::Dashboard::Stages::CommonMetricsInserter,
Gitlab::Metrics::Dashboard::Stages::CustomMetricsInserter,
Gitlab::Metrics::Dashboard::Stages::CustomMetricsDetailsInserter,
Gitlab::Metrics::Dashboard::Stages::EndpointInserter,
Gitlab::Metrics::Dashboard::Stages::MetricEndpointInserter,
Gitlab::Metrics::Dashboard::Stages::Sorter,
Gitlab::Metrics::Dashboard::Stages::AlertsInserter,
Gitlab::Metrics::Dashboard::Stages::PanelIdsInserter,
......@@ -98,7 +98,7 @@ describe Gitlab::Metrics::Dashboard::Processor do
let(:sequence) do
[
Gitlab::Metrics::Dashboard::Stages::CommonMetricsInserter,
Gitlab::Metrics::Dashboard::Stages::EndpointInserter,
Gitlab::Metrics::Dashboard::Stages::MetricEndpointInserter,
Gitlab::Metrics::Dashboard::Stages::Sorter
]
end
......
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::Metrics::Dashboard::Stages::VariableEndpointInserter do
include MetricsDashboardHelpers
let(:project) { build_stubbed(:project) }
let(:environment) { build_stubbed(:environment, project: project) }
describe '#transform!' do
subject(:transform!) { described_class.new(project, dashboard, environment: environment).transform! }
let(:dashboard) { load_sample_dashboard.deep_symbolize_keys }
context 'when dashboard variables are present' do
it 'assigns prometheus_endpoint_path to metric_label_values variable type' do
endpoint_path = Gitlab::Routing.url_helpers.prometheus_api_project_environment_path(
project,
environment,
proxy_path: :series,
match: ['backend:haproxy_backend_availability:ratio{env="{{env}}"}']
)
transform!
expect(
dashboard.dig(:templating, :variables, :metric_label_values_variable, :options)
).to include(prometheus_endpoint_path: endpoint_path)
end
it 'does not modify other variable types' do
original_text_variable = dashboard[:templating][:variables][:text_variable_full_syntax].deep_dup
transform!
expect(dashboard[:templating][:variables][:text_variable_full_syntax]).to eq(original_text_variable)
end
context 'when variable does not have the required series_selector' do
it 'adds prometheus_endpoint_path without match parameter' do
dashboard[:templating][:variables][:metric_label_values_variable][:options].delete(:series_selector)
endpoint_path = Gitlab::Routing.url_helpers.prometheus_api_project_environment_path(
project,
environment,
proxy_path: :series
)
transform!
expect(
dashboard.dig(:templating, :variables, :metric_label_values_variable, :options)
).to include(prometheus_endpoint_path: endpoint_path)
end
end
end
context 'when no variables are present' do
it 'does not fail' do
dashboard.delete(:templating)
expect { transform! }.not_to raise_error
end
end
context 'with no environment' do
subject(:transform!) { described_class.new(project, dashboard, {}).transform! }
it 'raises error' do
expect { transform! }.to raise_error(
Gitlab::Metrics::Dashboard::Errors::DashboardProcessingError,
'Environment is required for Stages::VariableEndpointInserter'
)
end
end
end
end
......@@ -18,6 +18,10 @@ module MetricsDashboardHelpers
project.repository.refresh_method_caches([:metrics_dashboard])
end
def load_sample_dashboard
YAML.safe_load(fixture_file('lib/gitlab/metrics/dashboard/sample_dashboard.yml'))
end
def system_dashboard_path
Metrics::Dashboard::SystemDashboardService::DASHBOARD_PATH
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment