module Kennel

encapsulates knowledge around how the api works especially 1-off weirdness that should not lak into other parts of the code

cache that reads everything from a single file

Not used in here, but in our templated repo … so keeping it around for now.

Show Alerts that are not muted and their alerting scopes

Constants

VERSION

Attributes

err[RW]
out[RW]

Public Class Methods

generate() click to toggle source
# File lib/kennel.rb, line 43
def generate
  store generated
end
plan() click to toggle source
# File lib/kennel.rb, line 47
def plan
  syncer.plan
end
update() click to toggle source
# File lib/kennel.rb, line 51
def update
  syncer.plan
  syncer.update if syncer.confirm
end

Private Class Methods

api() click to toggle source
# File lib/kennel.rb, line 91
def api
  @api ||= Api.new(ENV.fetch("DATADOG_APP_KEY"), ENV.fetch("DATADOG_API_KEY"))
end
generated() click to toggle source
# File lib/kennel.rb, line 95
    def generated
      @generated ||= begin
        Progress.progress "Generating" do
          load_all
          known = []
          parts = Models::Project.recursive_subclasses.flat_map do |project_class|
            project = project_class.new
            kennel_id = project.kennel_id
            if project_filter
              known << kennel_id
              next [] if kennel_id != project_filter
            end
            project.validated_parts
          end

          if project_filter && parts.empty?
            raise "#{project_filter} does not match any projects, try any of these:\n#{known.uniq.sort.join("\n")}"
          end

          parts.group_by(&:tracking_id).each do |tracking_id, same|
            next if same.size == 1
            raise <<~ERROR
              #{tracking_id} is defined #{same.size} times
              use a different `kennel_id` when defining multiple projects/monitors/dashboards to avoid this conflict
            ERROR
          end
          parts
        end
      end
    end
load_all() click to toggle source
# File lib/kennel.rb, line 130
def load_all
  ["teams", "parts", "projects"].each do |folder|
    Dir["#{folder}/**/*.rb"].sort.each { |f| require "./#{f}" }
  end
end
project_filter() click to toggle source
# File lib/kennel.rb, line 126
def project_filter
  ENV["PROJECT"]
end
store(parts) click to toggle source
# File lib/kennel.rb, line 58
def store(parts)
  Progress.progress "Storing" do
    old = Dir["generated/#{project_filter || "**"}/*"]
    used = []

    Utils.parallel(parts, max: 2) do |part|
      path = "generated/#{part.tracking_id.tr("/", ":").sub(":", "/")}.json"
      used << File.dirname(path) # only 1 level of sub folders, so this is safe
      used << path
      write_file_if_necessary(path, JSON.pretty_generate(part.as_json) << "\n")
    end

    # deleting all is slow, so only delete the extras
    (old - used).each { |p| FileUtils.rm_rf(p) }
  end
end
syncer() click to toggle source
# File lib/kennel.rb, line 87
def syncer
  @syncer ||= Syncer.new(api, generated, project: project_filter)
end
write_file_if_necessary(path, content) click to toggle source
# File lib/kennel.rb, line 75
def write_file_if_necessary(path, content)
  # 99% case
  begin
    return if File.read(path) == content
  rescue Errno::ENOENT
    FileUtils.mkdir_p(File.dirname(path))
  end

  # slow 1% case
  File.write(path, content)
end