kennel 1.13.1 → 1.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9a91ef82e0316c3472e8d917d9177d07cb4a6e51dad3c1fd916d13ac45dafd52
4
- data.tar.gz: 0dfe6fb42f7109fcd4477159fa84a608833c8f788d8868886043afca70ff338c
3
+ metadata.gz: 8cda7076e55a2d8b8d90e6112bed1573db8074c4dd85bf1ca4df4c409e9b6718
4
+ data.tar.gz: 2e081e9e843bd0c352d1e81dde8feb380d9866d8cf0a80f025f2432b656e844b
5
5
  SHA512:
6
- metadata.gz: 7cfd2e8aa8e763f6600f381289c7ecf01c94adaac847360f7dab279897b44cb56617d8a7e3e662b8bd076e5786de6ed455ee1c6f350d158e81596044046cadfd
7
- data.tar.gz: fe0599c3d7a13c16cd014a85345056dc4f7d71959b9d20d502bc26df68c72932d6e05489a2b8cb9782546eca640894d45d30755ac82f3acfa05bfb0b40ebdf9d
6
+ metadata.gz: ed7068f93ca8dc3ec3a9c6138710324032c70dae4e27cdd260f3976b6181c7d4ea281c105cacc18211b2d69feccc0461b76180d3503fc9a60aa92883f8b9a07c
7
+ data.tar.gz: a23491d09e81ff7ce8cb82d01522fe46a55bb851cd9300c8a6facbc788658d641cae1c8f678a80783f0f186a9ed0422b1f07c4958a2d61e317342245bbb809d0
@@ -13,6 +13,7 @@ require "kennel/subclass_tracking"
13
13
  require "kennel/file_cache"
14
14
  require "kennel/template_variables"
15
15
  require "kennel/optional_validations"
16
+ require "kennel/unmuted_alerts"
16
17
 
17
18
  require "kennel/models/base"
18
19
 
@@ -7,11 +7,11 @@ module Kennel
7
7
  @client = Faraday.new(url: "https://app.datadoghq.com")
8
8
  end
9
9
 
10
- def show(api_resource, id)
11
- request :get, "/api/v1/#{api_resource}/#{id}"
10
+ def show(api_resource, id, params = {})
11
+ request :get, "/api/v1/#{api_resource}/#{id}", params: params
12
12
  end
13
13
 
14
- def list(api_resource, params)
14
+ def list(api_resource, params = {})
15
15
  request :get, "/api/v1/#{api_resource}", params: params
16
16
  end
17
17
 
@@ -5,7 +5,7 @@ module Kennel
5
5
  class Progress
6
6
  # print what we are doing and a spinner until it is done ... then show how long it took
7
7
  def self.progress(name)
8
- print "#{name} ... "
8
+ $stderr.print "#{name} ... "
9
9
 
10
10
  animation = "-\\|/"
11
11
  count = 0
@@ -15,9 +15,9 @@ module Kennel
15
15
  spinner = Thread.new do
16
16
  loop do
17
17
  break if stop
18
- print animation[count % animation.size]
18
+ $stderr.print animation[count % animation.size]
19
19
  sleep 0.2
20
- print "\b"
20
+ $stderr.print "\b"
21
21
  count += 1
22
22
  end
23
23
  end
@@ -26,7 +26,7 @@ module Kennel
26
26
 
27
27
  stop = true
28
28
  spinner.join
29
- print "#{time.round(2)}s\n"
29
+ $stderr.print "#{time.round(2)}s\n"
30
30
 
31
31
  result
32
32
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  require "English"
3
3
  require "kennel"
4
+ require "kennel/unmuted_alerts"
4
5
 
5
6
  namespace :kennel do
6
7
  desc "Ensure there are no uncommited changes that would be hidden from PR reviewers"
@@ -42,6 +43,12 @@ namespace :kennel do
42
43
  end
43
44
  end
44
45
 
46
+ desc "show unmuted alerts filtered by TAG, for example TAG=team:foo"
47
+ task alerts: :environment do
48
+ tag = ENV["TAG"] || abort("Call with TAG=foo:bar")
49
+ Kennel::UnmutedAlerts.print(Kennel.send(:api), tag)
50
+ end
51
+
45
52
  task :environment do
46
53
  require "kennel"
47
54
  gem "dotenv"
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+ require "kennel"
3
+
4
+ # Show Alerts that are not muted and their alerting scopes
5
+ module Kennel
6
+ class UnmutedAlerts
7
+ class << self
8
+ def print(api, tag)
9
+ monitors = filtered_monitors(api, tag)
10
+ if monitors.empty?
11
+ puts "No unmuted alerts found"
12
+ else
13
+ monitors.each do |m|
14
+ puts m[:name]
15
+ puts Utils.path_to_url("/monitors/#{m[:id]}")
16
+ m[:state][:groups].each { |g| puts "#{g[:status]}\t#{g[:name]}" }
17
+ puts
18
+ end
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ # sort pod3 before pod11
25
+ def sort_groups!(monitor)
26
+ groups = monitor[:state][:groups].values
27
+ groups.sort_by! { |g| g[:name].to_s.split(",").map { |w| Utils.natural_order(w) } }
28
+ monitor[:state][:groups] = groups
29
+ end
30
+
31
+ def filtered_monitors(api, tag)
32
+ # Download all monitors
33
+ monitors = Progress.progress("Downloading") do
34
+ api.list("monitor")
35
+ end
36
+
37
+ # only keep monitors from selected tag
38
+ monitors.select! { |m| m[:tags].include? tag }
39
+ raise "No monitors for #{tag} found, check your spelling" if monitors.empty?
40
+
41
+ # only keep monitors that are alerting or not silenced
42
+ monitors.select! { |m| m[:overall_state] != "OK" && !m[:options][:silenced].key?(:*) }
43
+
44
+ # get state details to romove silenced alerts
45
+ Progress.progress("Getting monitor details") do
46
+ monitors = Utils.parallel(monitors) do |m|
47
+ api.show("monitor", m.fetch(:id), group_states: "all")
48
+ end
49
+ end
50
+
51
+ # only keep groups that are alerting
52
+ monitors.each { |m| m[:state][:groups].reject! { |_, g| g[:status] == "OK" } }
53
+
54
+ # only keep alerting groups that are not silenced
55
+ monitors.each do |m|
56
+ silenced = m[:options][:silenced].keys.map { |k| k.to_s.split(",") }
57
+ m[:state][:groups].select! do |k, _|
58
+ scope = k.to_s.split(",")
59
+ silenced.none? { |s| (s - scope).empty? }
60
+ end
61
+ end
62
+
63
+ # only keep monitors with alerting groups
64
+ monitors.select! { |m| m[:state][:groups].any? }
65
+
66
+ # sort group alerts
67
+ monitors.each { |m| sort_groups!(m) }
68
+ end
69
+ end
70
+ end
71
+ end
@@ -24,11 +24,11 @@ module Kennel
24
24
  end
25
25
 
26
26
  def ask(question)
27
- printf color(:red, "#{question} - press 'y' to continue: ")
27
+ $stderr.printf color(:red, "#{question} - press 'y' to continue: ")
28
28
  begin
29
29
  STDIN.gets.chomp == "y"
30
30
  rescue Interrupt # do not show a backtrace if user decides to Ctrl+C here
31
- printf "\n"
31
+ $stderr.print "\n"
32
32
  exit 1
33
33
  end
34
34
  end
@@ -96,6 +96,10 @@ module Kennel
96
96
  end
97
97
  end.map(&:value).each { |i| raise i if i.is_a?(StandardError) }
98
98
  end
99
+
100
+ def natural_order(name)
101
+ name.split(/(\d+)/).each_with_index.map { |x, i| i.odd? ? x.to_i : x }
102
+ end
99
103
  end
100
104
  end
101
105
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Kennel
3
- VERSION = "1.13.1"
3
+ VERSION = "1.14.0"
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kennel
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.13.1
4
+ version: 1.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Grosser
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-09-18 00:00:00.000000000 Z
11
+ date: 2018-10-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: faraday
@@ -60,6 +60,7 @@ files:
60
60
  - lib/kennel/syncer.rb
61
61
  - lib/kennel/tasks.rb
62
62
  - lib/kennel/template_variables.rb
63
+ - lib/kennel/unmuted_alerts.rb
63
64
  - lib/kennel/utils.rb
64
65
  - lib/kennel/version.rb
65
66
  homepage: https://github.com/grosser/kennel