gitlab-org--gitlab-foss/app/models/performance_monitoring/prometheus_dashboard.rb

86 lines
2.9 KiB
Ruby

# frozen_string_literal: true
module PerformanceMonitoring
class PrometheusDashboard
include ActiveModel::Model
attr_accessor :dashboard, :panel_groups, :path, :environment, :priority, :templating, :links
validates :dashboard, presence: true
validates :panel_groups, array_members: { member_class: PerformanceMonitoring::PrometheusPanelGroup }
class << self
def from_json(json_content)
build_from_hash(json_content).tap(&:validate!)
end
def find_for(project:, user:, path:, options: {})
template = { path: path, environment: options[:environment] }
rsp = Gitlab::Metrics::Dashboard::Finder.find(project, user, options.merge(dashboard_path: path))
case rsp[:http_status] || rsp[:status]
when :success
new(template.merge(rsp[:dashboard] || {})) # when there is empty dashboard file returned rsp is still a success
when :unprocessable_entity
new(template) # validation error
else
nil # any other error
end
end
private
def build_from_hash(attributes)
return new unless attributes.is_a?(Hash)
new(
dashboard: attributes['dashboard'],
panel_groups: initialize_children_collection(attributes['panel_groups'])
)
end
def initialize_children_collection(children)
return unless children.is_a?(Array)
children.map { |group| PerformanceMonitoring::PrometheusPanelGroup.from_json(group) }
end
end
def to_yaml
self.as_json(only: yaml_valid_attributes).to_yaml
end
# This method is planned to be refactored as a part of https://gitlab.com/gitlab-org/gitlab/-/issues/219398
# implementation. For new existing logic was reused to faster deliver MVC
def schema_validation_warnings
return run_custom_validation.map(&:message) if Feature.enabled?(:metrics_dashboard_exhaustive_validations, environment&.project)
self.class.from_json(reload_schema)
[]
rescue Gitlab::Metrics::Dashboard::Errors::LayoutError => e
[e.message]
rescue ActiveModel::ValidationError => e
e.model.errors.map { |attr, error| "#{attr}: #{error}" }
end
private
def run_custom_validation
Gitlab::Metrics::Dashboard::Validator
.errors(reload_schema, dashboard_path: path, project: environment&.project)
end
# dashboard finder methods are somehow limited, #find includes checking if
# user is authorised to view selected dashboard, but modifies schema, which in some cases may
# cause false positives returned from validation, and #find_raw does not authorise users
def reload_schema
project = environment&.project
project.nil? ? self.as_json : Gitlab::Metrics::Dashboard::Finder.find_raw(project, dashboard_path: path)
end
def yaml_valid_attributes
%w(panel_groups panels metrics group priority type title y_label weight id unit label query query_range dashboard)
end
end
end