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"
  },
  "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



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

def api_resource
  "dashboard"
end

.normalize(expected, actual) ⇒ Object



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

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 change on every update so we always discard them
  end
end

.parse_url(url) ⇒ Object



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

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

.url(id) ⇒ Object



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

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

Instance Method Details

#build_jsonObject



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

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



179
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
# File 'lib/kennel/models/dashboard.rb', line 179

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



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

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