Commit caa361b7 authored by Sarah Yasonik's avatar Sarah Yasonik Committed by Mayra Cabrera

Support query parameters in metrics embeds

https://gitlab.com/gitlab-org/gitlab-ce/issues/62971

Adds support for embedding specific charts from the
metrics dashboard. Expected parameters are dashboard,
title, group, and y_label.
parent e6c0f6b0
---
title: Enable embedding of specific metrics charts in GFM
merge_request: 31304
author:
type: added
...@@ -15,17 +15,6 @@ module Banzai ...@@ -15,17 +15,6 @@ module Banzai
) )
end end
# Endpoint FE should hit to collect the appropriate
# chart information
def metrics_dashboard_url(params)
Gitlab::Metrics::Dashboard::Url.build_dashboard_url(
params['namespace'],
params['project'],
params['environment'],
embedded: true
)
end
# Search params for selecting metrics links. A few # Search params for selecting metrics links. A few
# simple checks is enough to boost performance without # simple checks is enough to boost performance without
# the cost of doing a full regex match. # the cost of doing a full regex match.
...@@ -38,6 +27,28 @@ module Banzai ...@@ -38,6 +27,28 @@ module Banzai
def link_pattern def link_pattern
Gitlab::Metrics::Dashboard::Url.regex Gitlab::Metrics::Dashboard::Url.regex
end end
private
# Endpoint FE should hit to collect the appropriate
# chart information
def metrics_dashboard_url(params)
Gitlab::Metrics::Dashboard::Url.build_dashboard_url(
params['namespace'],
params['project'],
params['environment'],
embedded: true,
**query_params(params['url'])
)
end
# Parses query params out from full url string into hash.
#
# Ex) 'https://<root>/<project>/<environment>/metrics?title=Title&group=Group'
# --> { title: 'Title', group: 'Group' }
def query_params(url)
Gitlab::Metrics::Dashboard::Url.parse_query(url)
end
end end
end end
end end
...@@ -21,14 +21,26 @@ module Gitlab ...@@ -21,14 +21,26 @@ module Gitlab
\/(?<environment>\d+) \/(?<environment>\d+)
\/metrics \/metrics
(?<query> (?<query>
\?[a-z0-9_=-]+ \?[a-zA-Z0-9%.()+_=-]+
(&[a-z0-9_=-]+)* (&[a-zA-Z0-9%.()+_=-]+)*
)? )?
(?<anchor>\#[a-z0-9_-]+)? (?<anchor>\#[a-z0-9_-]+)?
) )
}x }x
end end
# Parses query params out from full url string into hash.
#
# Ex) 'https://<root>/<project>/<environment>/metrics?title=Title&group=Group'
# --> { title: 'Title', group: 'Group' }
def parse_query(url)
query_string = URI.parse(url).query.to_s
CGI.parse(query_string)
.transform_values { |value| value.first }
.symbolize_keys
end
# Builds a metrics dashboard url based on the passed in arguments # Builds a metrics dashboard url based on the passed in arguments
def build_dashboard_url(*args) def build_dashboard_url(*args)
Gitlab::Routing.url_helpers.metrics_dashboard_namespace_project_environment_url(*args) Gitlab::Routing.url_helpers.metrics_dashboard_namespace_project_environment_url(*args)
......
...@@ -26,7 +26,6 @@ describe 'Metrics rendering', :js, :use_clean_rails_memory_store_caching do ...@@ -26,7 +26,6 @@ describe 'Metrics rendering', :js, :use_clean_rails_memory_store_caching do
restore_host restore_host
end end
context 'with deployments and related deployable present' do
it 'shows embedded metrics' do it 'shows embedded metrics' do
visit project_issue_path(project, issue) visit project_issue_path(project, issue)
...@@ -34,6 +33,25 @@ describe 'Metrics rendering', :js, :use_clean_rails_memory_store_caching do ...@@ -34,6 +33,25 @@ describe 'Metrics rendering', :js, :use_clean_rails_memory_store_caching do
expect(page).to have_text('Memory Usage (Total)') expect(page).to have_text('Memory Usage (Total)')
expect(page).to have_text('Core Usage (Total)') expect(page).to have_text('Core Usage (Total)')
end end
context 'when dashboard params are in included the url' do
let(:metrics_url) { metrics_project_environment_url(project, environment, **chart_params) }
let(:chart_params) do
{
group: 'System metrics (Kubernetes)',
title: 'Memory Usage (Pod average)',
y_label: 'Memory Used per Pod (MB)'
}
end
it 'shows embedded metrics for the specifiec chart' do
visit project_issue_path(project, issue)
expect(page).to have_css('div.prometheus-graph')
expect(page).to have_text(chart_params[:title])
expect(page).to have_text(chart_params[:y_label])
end
end end
def import_common_metrics def import_common_metrics
......
...@@ -12,7 +12,7 @@ describe Banzai::Filter::InlineMetricsFilter do ...@@ -12,7 +12,7 @@ describe Banzai::Filter::InlineMetricsFilter do
let(:url) { 'https://foo.com' } let(:url) { 'https://foo.com' }
it 'leaves regular non-metrics links unchanged' do it 'leaves regular non-metrics links unchanged' do
expect(doc.to_s).to eq input expect(doc.to_s).to eq(input)
end end
end end
...@@ -21,7 +21,7 @@ describe Banzai::Filter::InlineMetricsFilter do ...@@ -21,7 +21,7 @@ describe Banzai::Filter::InlineMetricsFilter do
let(:url) { urls.metrics_namespace_project_environment_url(*params) } let(:url) { urls.metrics_namespace_project_environment_url(*params) }
it 'leaves the original link unchanged' do it 'leaves the original link unchanged' do
expect(doc.at_css('a').to_s).to eq input expect(doc.at_css('a').to_s).to eq(input)
end end
it 'appends a metrics charts placeholder with dashboard url after metrics links' do it 'appends a metrics charts placeholder with dashboard url after metrics links' do
...@@ -29,7 +29,7 @@ describe Banzai::Filter::InlineMetricsFilter do ...@@ -29,7 +29,7 @@ describe Banzai::Filter::InlineMetricsFilter do
expect(node).to be_present expect(node).to be_present
dashboard_url = urls.metrics_dashboard_namespace_project_environment_url(*params, embedded: true) dashboard_url = urls.metrics_dashboard_namespace_project_environment_url(*params, embedded: true)
expect(node.attribute('data-dashboard-url').to_s).to eq dashboard_url expect(node.attribute('data-dashboard-url').to_s).to eq(dashboard_url)
end end
context 'when the metrics dashboard link is part of a paragraph' do context 'when the metrics dashboard link is part of a paragraph' do
...@@ -37,9 +37,34 @@ describe Banzai::Filter::InlineMetricsFilter do ...@@ -37,9 +37,34 @@ describe Banzai::Filter::InlineMetricsFilter do
let(:input) { %(<p>#{paragraph}</p>) } let(:input) { %(<p>#{paragraph}</p>) }
it 'appends the charts placeholder after the enclosing paragraph' do it 'appends the charts placeholder after the enclosing paragraph' do
expect(doc.at_css('p').to_s).to include paragraph expect(doc.at_css('p').to_s).to include(paragraph)
expect(doc.at_css('.js-render-metrics')).to be_present expect(doc.at_css('.js-render-metrics')).to be_present
end end
end end
context 'with dashboard params specified' do
let(:params) do
[
'foo',
'bar',
12,
{
embedded: true,
dashboard: 'config/prometheus/common_metrics.yml',
group: 'System metrics (Kubernetes)',
title: 'Core Usage (Pod Average)',
y_label: 'Cores per Pod'
}
]
end
it 'appends a metrics charts placeholder with dashboard url after metrics links' do
node = doc.at_css('.js-render-metrics')
expect(node).to be_present
dashboard_url = urls.metrics_dashboard_namespace_project_environment_url(*params)
expect(node.attribute('data-dashboard-url').to_s).to eq(dashboard_url)
end
end
end end
end end
...@@ -9,14 +9,22 @@ describe Gitlab::Metrics::Dashboard::Url do ...@@ -9,14 +9,22 @@ describe Gitlab::Metrics::Dashboard::Url do
end end
it 'matches a metrics dashboard link with named params' do it 'matches a metrics dashboard link with named params' do
url = Gitlab::Routing.url_helpers.metrics_namespace_project_environment_url('foo', 'bar', 1, start: 123345456, anchor: 'title') url = Gitlab::Routing.url_helpers.metrics_namespace_project_environment_url(
'foo',
'bar',
1,
start: '2019-08-02T05:43:09.000Z',
dashboard: 'config/prometheus/common_metrics.yml',
group: 'awesome group',
anchor: 'title'
)
expected_params = { expected_params = {
'url' => url, 'url' => url,
'namespace' => 'foo', 'namespace' => 'foo',
'project' => 'bar', 'project' => 'bar',
'environment' => '1', 'environment' => '1',
'query' => '?start=123345456', 'query' => '?dashboard=config%2Fprometheus%2Fcommon_metrics.yml&group=awesome+group&start=2019-08-02T05%3A43%3A09.000Z',
'anchor' => '#title' 'anchor' => '#title'
} }
......
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