Commit 4ca4241f authored by Mikolaj Wawrzyniak's avatar Mikolaj Wawrzyniak

Fix metrics dashboard YAML validaiton

For files which does not contain hash valdiation raised 500 errors
to avoid that, we need to check in before if passed contet is a hash.
parent b839e74f
...@@ -11,12 +11,7 @@ module PerformanceMonitoring ...@@ -11,12 +11,7 @@ module PerformanceMonitoring
class << self class << self
def from_json(json_content) def from_json(json_content)
dashboard = new( build_from_hash(json_content).tap(&:validate!)
dashboard: json_content['dashboard'],
panel_groups: json_content['panel_groups']&.map { |group| PrometheusPanelGroup.from_json(group) }
)
dashboard.tap(&:validate!)
end end
def find_for(project:, user:, path:, options: {}) def find_for(project:, user:, path:, options: {})
...@@ -30,6 +25,17 @@ module PerformanceMonitoring ...@@ -30,6 +25,17 @@ module PerformanceMonitoring
}.merge(dashboard_response[:dashboard]) }.merge(dashboard_response[:dashboard])
) )
end end
private
def build_from_hash(attributes)
return new unless attributes.is_a?(Hash)
new(
dashboard: attributes['dashboard'],
panel_groups: attributes['panel_groups']&.map { |group| PrometheusPanelGroup.from_json(group) }
)
end
end end
def to_yaml def to_yaml
......
...@@ -10,16 +10,24 @@ module PerformanceMonitoring ...@@ -10,16 +10,24 @@ module PerformanceMonitoring
validates :query, presence: true, unless: :query_range validates :query, presence: true, unless: :query_range
validates :query_range, presence: true, unless: :query validates :query_range, presence: true, unless: :query
def self.from_json(json_content) class << self
metric = PrometheusMetric.new( def from_json(json_content)
id: json_content['id'], build_from_hash(json_content).tap(&:validate!)
unit: json_content['unit'], end
label: json_content['label'],
query: json_content['query'],
query_range: json_content['query_range']
)
metric.tap(&:validate!) private
def build_from_hash(attributes)
return new unless attributes.is_a?(Hash)
new(
id: attributes['id'],
unit: attributes['unit'],
label: attributes['label'],
query: attributes['query'],
query_range: attributes['query_range']
)
end
end end
end end
end end
...@@ -8,17 +8,24 @@ module PerformanceMonitoring ...@@ -8,17 +8,24 @@ module PerformanceMonitoring
validates :title, presence: true validates :title, presence: true
validates :metrics, presence: true validates :metrics, presence: true
class << self
def from_json(json_content)
build_from_hash(json_content).tap(&:validate!)
end
def self.from_json(json_content) private
panel = new(
type: json_content['type'],
title: json_content['title'],
y_label: json_content['y_label'],
weight: json_content['weight'],
metrics: json_content['metrics']&.map { |metric| PrometheusMetric.from_json(metric) }
)
panel.tap(&:validate!) def build_from_hash(attributes)
return new unless attributes.is_a?(Hash)
new(
type: attributes['type'],
title: attributes['title'],
y_label: attributes['y_label'],
weight: attributes['weight'],
metrics: attributes['metrics']&.map { |metric| PrometheusMetric.from_json(metric) }
)
end
end end
def id(group_title) def id(group_title)
......
...@@ -8,15 +8,22 @@ module PerformanceMonitoring ...@@ -8,15 +8,22 @@ module PerformanceMonitoring
validates :group, presence: true validates :group, presence: true
validates :panels, presence: true validates :panels, presence: true
class << self
def from_json(json_content)
build_from_hash(json_content).tap(&:validate!)
end
def self.from_json(json_content) private
panel_group = new(
group: json_content['group'],
priority: json_content['priority'],
panels: json_content['panels']&.map { |panel| PrometheusPanel.from_json(panel) }
)
panel_group.tap(&:validate!) def build_from_hash(attributes)
return new unless attributes.is_a?(Hash)
new(
group: attributes['group'],
priority: attributes['priority'],
panels: attributes['panels']&.map { |panel| PrometheusPanel.from_json(panel) }
)
end
end end
end end
end end
---
title: Fixed dashboard YAML file validaiton for files which do not contain object
as root element
merge_request: 33935
author:
type: fixed
...@@ -47,6 +47,24 @@ describe PerformanceMonitoring::PrometheusDashboard do ...@@ -47,6 +47,24 @@ describe PerformanceMonitoring::PrometheusDashboard do
end end
end end
context 'dashboard content is missing' do
let(:json_content) { nil }
it_behaves_like 'validation failed', panel_groups: ["can't be blank"], dashboard: ["can't be blank"]
end
context 'dashboard content is NOT a hash' do
let(:json_content) { YAML.safe_load("'test'") }
it_behaves_like 'validation failed', panel_groups: ["can't be blank"], dashboard: ["can't be blank"]
end
context 'content is an array' do
let(:json_content) { [{ "dashboard" => "Dashboard Title" }] }
it_behaves_like 'validation failed', panel_groups: ["can't be blank"], dashboard: ["can't be blank"]
end
context 'dashboard definition is missing panels_groups and dashboard keys' do context 'dashboard definition is missing panels_groups and dashboard keys' do
let(:json_content) do let(:json_content) do
{ {
......
...@@ -24,6 +24,14 @@ describe PerformanceMonitoring::PrometheusMetric do ...@@ -24,6 +24,14 @@ describe PerformanceMonitoring::PrometheusMetric do
end end
describe 'validations' do describe 'validations' do
context 'json_content is not a hash' do
let(:json_content) { nil }
subject { described_class.from_json(json_content) }
it { expect { subject }.to raise_error(ActiveModel::ValidationError) }
end
context 'when unit is missing' do context 'when unit is missing' do
before do before do
json_content['unit'] = nil json_content['unit'] = nil
......
...@@ -30,6 +30,14 @@ describe PerformanceMonitoring::PrometheusPanelGroup do ...@@ -30,6 +30,14 @@ describe PerformanceMonitoring::PrometheusPanelGroup do
end end
describe 'validations' do describe 'validations' do
context 'json_content is not a hash' do
let(:json_content) { nil }
subject { described_class.from_json(json_content) }
it { expect { subject }.to raise_error(ActiveModel::ValidationError) }
end
context 'when group is missing' do context 'when group is missing' do
before do before do
json_content.delete('group') json_content.delete('group')
......
...@@ -42,6 +42,14 @@ describe PerformanceMonitoring::PrometheusPanel do ...@@ -42,6 +42,14 @@ describe PerformanceMonitoring::PrometheusPanel do
end end
describe 'validations' do describe 'validations' do
context 'json_content is not a hash' do
let(:json_content) { nil }
subject { described_class.from_json(json_content) }
it { expect { subject }.to raise_error(ActiveModel::ValidationError) }
end
context 'when title is missing' do context 'when title is missing' do
before do before do
json_content['title'] = nil json_content['title'] = nil
......
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