Class: Kennel::Models::Dashboard

Inherits:
Record show all
Includes:
TagsValidation, TemplateVariables
Defined in:
lib/kennel/models/dashboard.rb

Constant Summary collapse

READONLY_ATTRIBUTES =
superclass::READONLY_ATTRIBUTES + [
  :author_handle, :author_name, :modified_at, :deleted_at, :url, :is_read_only, :notify_list, :restricted_roles,
  :experience_type
]
TRACKING_FIELD =
:description
REQUEST_DEFAULTS =
{
  style: { line_width: "normal", palette: "dog_classic", line_type: "solid" }
}.freeze
WIDGET_DEFAULTS =
{
  "timeseries" => {
    legend_size: "0",
    markers: [],
    legend_columns: [
      "avg",
      "min",
      "max",
      "value",
      "sum"
    ],
    legend_layout: "auto",
    yaxis: {
      include_zero: true,
      label: "",
      scale: "linear",
      min: "auto",
      max: "auto"
    },
    time: {},
    title_align: "left",
    title_size: "16",
    show_legend: true
  },
  "note" => {
    show_tick: false,
    tick_edge: "left",
    tick_pos: "50%",
    text_align: "left",
    has_padding: true,
    background_color: "white",
    font_size: "14"
  },
  "query_value" => {
    time: {},
    title_align: "left",
    title_size: "16"
  },
  "free_text" => {
    font_size: "auto"
  },
  "check_status" => {
    title_align: "left",
    title_size: "16"
  },
  "slo" => {
    global_time_target: "0",
    title_align: "left",
    title_size: "16"
  },
  "query_table" => {
    title_align: "left",
    title_size: "16"
  }
}.freeze
SUPPORTED_DEFINITION_OPTIONS =
[:events, :markers, :precision].freeze
DEFAULTS =
{
  template_variable_presets: nil
}.freeze
TAG_PREFIX =
/^team:/

Constants inherited from Record

Record::ALLOWED_KENNEL_ID_CHARS, Record::ALLOWED_KENNEL_ID_FULL, Record::ALLOWED_KENNEL_ID_REGEX, Record::ALLOWED_KENNEL_ID_SEGMENT, Record::LOCK, Record::MARKER_TEXT, Record::TITLE_FIELDS, Record::TRACKING_FIELDS

Constants included from OptionalValidations

OptionalValidations::UNIGNORABLE, OptionalValidations::UNUSED_IGNORES

Constants inherited from Base

Base::SETTING_OVERRIDABLE_METHODS

Constants included from SettingsAsMethods

SettingsAsMethods::AS_PROCS, SettingsAsMethods::SETTING_OVERRIDABLE_METHODS

Instance Attribute Summary

Attributes inherited from Record

#as_json, #project

Class Method Summary collapse

Instance Method Summary collapse

Methods included from TemplateVariables

included

Methods inherited from Record

#add_tracking_id, api_resource_map, #build, #diff, #initialize, #invalid_update!, parse_any_url, parse_tracking_id, #remove_tracking_id, remove_tracking_id, #safe_tracking_id, #tracking_id

Methods included from OptionalValidations

filter_validation_errors, included, #initialize, #invalid!, valid?

Methods inherited from Base

#kennel_id, #name, #to_json

Methods included from SubclassTracking

#recursive_subclasses, #subclasses

Methods included from SettingsAsMethods

included, #initialize, #raise_with_location

Constructor Details

This class inherits a constructor from Kennel::Models::Record

Class Method Details

.api_resourceObject



94
95
96
# File 'lib/kennel/models/dashboard.rb', line 94

def api_resource
  "dashboard"
end

.normalize(expected, actual) ⇒ Object



98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/kennel/models/dashboard.rb', line 98

def normalize(expected, actual)
  super

  ignore_default expected, actual, DEFAULTS
  ignore_default expected, actual, reflow_type: "auto" if expected[:layout_type] == "ordered"

  widgets_pairs(expected, actual).each do |pair|
    pair.each { |w| sort_conditional_formats w }
    ignore_widget_defaults(*pair)
    ignore_request_defaults(*pair)
    pair.each { |widget| widget&.delete(:id) } # ids are kinda random so we always discard them
  end
end

.parse_url(url) ⇒ Object



176
177
178
# File 'lib/kennel/models/dashboard.rb', line 176

def self.parse_url(url)
  url[/\/dashboard\/([a-z\d-]+)/, 1]
end

.url(id) ⇒ Object



172
173
174
# File 'lib/kennel/models/dashboard.rb', line 172

def self.url(id)
  Utils.path_to_url "/dashboard/#{id}"
end

Instance Method Details

#build_jsonObject



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/kennel/models/dashboard.rb', line 154

def build_json
  all_widgets = render_definitions(definitions) + widgets
  expand_q all_widgets
  json = super.merge(
    layout_type: layout_type,
    title: "#{title}#{LOCK}",
    description: description,
    template_variables: render_template_variables,
    template_variable_presets: template_variable_presets,
    widgets: all_widgets,
    tags: tags.grep(TAG_PREFIX)
  )

  json[:reflow_type] = reflow_type if reflow_type # setting nil breaks create with "ordered"

  json
end

#resolve_linked_tracking_ids!(id_map, **args) ⇒ Object



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/kennel/models/dashboard.rb', line 180

def resolve_linked_tracking_ids!(id_map, **args)
  widgets = as_json[:widgets].flat_map { |w| [w, *w.dig(:definition, :widgets) || []] }
  widgets.each do |widget|
    next unless (definition = widget[:definition])
    case definition[:type]
    when "uptime"
      if (ids = definition[:monitor_ids])
        definition[:monitor_ids] = ids.map do |id|
          resolve(id, :monitor, id_map, **args) || id
        end
      end
    when "alert_graph"
      if (id = definition[:alert_id])
        resolved = resolve(id, :monitor, id_map, **args) || id
        definition[:alert_id] = resolved.to_s # even though it's a monitor id
      end
    when "slo"
      if (id = definition[:slo_id])
        definition[:slo_id] = resolve(id, :slo, id_map, **args) || id
      end
    when "timeseries"
      definition[:requests]&.each do |request|
        request[:queries]&.each do |query|
          if query[:data_source] == "slo" && (slo_id = query[:slo_id])
            query[:slo_id] = resolve(slo_id, :slo, id_map, **args) || slo_id
          end
        end
      end
    end
  end
end

#validate_update!(diffs) ⇒ Object



212
213
214
215
# File 'lib/kennel/models/dashboard.rb', line 212

def validate_update!(diffs)
  _, path, from, to = diffs.find { |diff| diff[1] == "layout_type" }
  invalid_update!(path, from, to) if path
end