doggy 2.1.1 → 3.0.0.pre.beta1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 782b3d86af1a0b64f7ddd7816230e1a159e95ab32e22912e9e4aadbdefde5c82
4
- data.tar.gz: 7e61f95d945bbd721e2f2ca2ee6070f84940a922dfbf0ec7298c4e77f247cd94
3
+ metadata.gz: af6510f8934d8d58b5f5cf9a318c7c4fd66893651cc1fcf9c24db4ebfb46e56b
4
+ data.tar.gz: 264f30ed2bd2ea394a29cc780c266f5345c092dc485ea7eca742cf00d9f6505f
5
5
  SHA512:
6
- metadata.gz: 05f92c7090313cfb21727e5159a6232532cd44f57ef565c837662f6aa3ed8e6a75a49ce86bda5609acfcb7c3e6384228b05d112dc5ab975894a658ea0508d433
7
- data.tar.gz: 7bf88190e67e97e33cfee61a57d83f7f14e15e2889b3384eea86b2d1fd92780307a7e4adafe49d32ee6579446f24d53cc51fc877906ece9b8604cf0b59da0a5a
6
+ metadata.gz: a7e116d5a61c47f44639695c245d3377c501a826935b33c39fa1b6d5ac487fef6f26ad6bc6395f572311d8101d129c544bac3366b08953fe48dbfeee897f551d
7
+ data.tar.gz: 55d8c1a9a3bb4797817d6ab012309e45a68855959c3bab9c47081e1ee85f354d0309dd1fbbbdfef2a7321fdbe9985bbd1eb020c4d4538945a10014b88e21f964
data/Gemfile.lock CHANGED
@@ -1,12 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- doggy (2.1.1)
4
+ doggy (3.0.0.pre.beta1)
5
5
  activesupport
6
6
  parallel
7
7
  rugged
8
8
  thor
9
- virtus
10
9
 
11
10
  GEM
12
11
  remote: https://rubygems.org/
@@ -19,23 +18,13 @@ GEM
19
18
  addressable (2.6.0)
20
19
  public_suffix (>= 2.0.2, < 4.0)
21
20
  ast (2.4.0)
22
- axiom-types (0.1.1)
23
- descendants_tracker (~> 0.0.4)
24
- ice_nine (~> 0.11.0)
25
- thread_safe (~> 0.3, >= 0.3.1)
26
21
  coderay (1.1.2)
27
- coercible (1.0.0)
28
- descendants_tracker (~> 0.0.1)
29
22
  concurrent-ruby (1.1.5)
30
23
  crack (0.4.3)
31
24
  safe_yaml (~> 1.0.0)
32
- descendants_tracker (0.0.4)
33
- thread_safe (~> 0.3, >= 0.3.1)
34
- equalizer (0.0.11)
35
- hashdiff (0.3.8)
25
+ hashdiff (0.3.9)
36
26
  i18n (1.6.0)
37
27
  concurrent-ruby (~> 1.0)
38
- ice_nine (0.11.2)
39
28
  jaro_winkler (1.5.2)
40
29
  metaclass (0.0.4)
41
30
  method_source (0.9.2)
@@ -43,7 +32,7 @@ GEM
43
32
  mocha (1.8.0)
44
33
  metaclass (~> 0.0.1)
45
34
  parallel (1.17.0)
46
- parser (2.6.2.1)
35
+ parser (2.6.3.0)
47
36
  ast (~> 2.4.0)
48
37
  pry (0.12.2)
49
38
  coderay (~> 1.1.0)
@@ -68,11 +57,6 @@ GEM
68
57
  tzinfo (1.2.5)
69
58
  thread_safe (~> 0.1)
70
59
  unicode-display_width (1.5.0)
71
- virtus (1.0.5)
72
- axiom-types (~> 0.1)
73
- coercible (~> 1.0)
74
- descendants_tracker (~> 0.0, >= 0.0.3)
75
- equalizer (~> 0.0, >= 0.0.9)
76
60
  webmock (3.5.1)
77
61
  addressable (>= 2.3.6)
78
62
  crack (>= 0.3.2)
data/README.md CHANGED
@@ -30,10 +30,6 @@ Export `DATADOG_API_KEY` and `DATADOG_APP_KEY` environment variables and `doggy`
30
30
 
31
31
  Optional: You can set `DATADOG_BASE_HUMAN_URL` environment variable if your organization uses a custom domain. This will change the urls given to users.
32
32
 
33
- #### ejson
34
-
35
- Set up `ejson` by putting `secrets.ejson` in your root object store.
36
-
37
33
  #### json (plaintext)
38
34
 
39
35
  If you're feeling adventurous, just put plaintext `secrets.json` in your root object store like this:
data/dev.yml CHANGED
@@ -4,7 +4,7 @@ up:
4
4
  - homebrew:
5
5
  - cmake
6
6
  - ruby:
7
- version: 2.6.2
7
+ version: 2.6.3
8
8
  - bundler
9
9
  commands:
10
10
  console:
data/doggy.gemspec CHANGED
@@ -1,13 +1,8 @@
1
- # coding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
- lib = File.expand_path('../lib', __FILE__)
5
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
- require 'doggy/version'
7
-
8
3
  Gem::Specification.new do |spec|
9
4
  spec.name = "doggy"
10
- spec.version = Doggy::VERSION
5
+ spec.version = "3.0.0-beta1"
11
6
  spec.authors = ["Vlad Gorodetsky", "Andre Medeiros"]
12
7
  spec.email = ["v@gor.io", "me@andremedeiros.info"]
13
8
 
@@ -25,13 +20,12 @@ Gem::Specification.new do |spec|
25
20
 
26
21
  spec.add_runtime_dependency("parallel")
27
22
  spec.add_runtime_dependency("thor")
28
- spec.add_runtime_dependency("virtus")
29
23
  spec.add_runtime_dependency("rugged")
30
- spec.add_runtime_dependency('activesupport')
24
+ spec.add_runtime_dependency("activesupport")
31
25
 
32
26
  spec.add_development_dependency("bundler")
33
27
  spec.add_development_dependency("rake")
34
28
  spec.add_development_dependency("minitest")
35
- spec.add_development_dependency('pry')
36
- spec.add_development_dependency('rubocop')
29
+ spec.add_development_dependency("pry")
30
+ spec.add_development_dependency("rubocop")
37
31
  end
data/lib/doggy.rb CHANGED
@@ -1,10 +1,10 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  require "pathname"
5
4
  require "net/http"
6
5
  require "rugged"
7
6
 
7
+ require "doggy/hash_sort"
8
8
  require "doggy/cli"
9
9
  require "doggy/cli/edit"
10
10
  require "doggy/cli/mute"
@@ -15,12 +15,10 @@ require "doggy/cli/delete"
15
15
  require "doggy/model"
16
16
  require "doggy/models/dashboard"
17
17
  require "doggy/models/monitor"
18
- require "doggy/models/screen"
19
- require "doggy/version"
20
18
 
21
19
  module Doggy
22
- DOG_SKIP_REGEX = /\xF0\x9F\x98\xB1|:scream:/i.freeze
23
- MANAGED_BY_DOGGY_REGEX = /\xF0\x9F\x90\xB6|:dog:/i.freeze
20
+ DOG_SKIP_REGEX = /😱|:scream:/i.freeze
21
+ MANAGED_BY_DOGGY_REGEX = /🐶|:dog:/i.freeze
24
22
 
25
23
  class DoggyError < StandardError; end
26
24
 
data/lib/doggy/cli.rb CHANGED
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  require "thor"
@@ -7,13 +6,6 @@ module Doggy
7
6
  class CLI < Thor
8
7
  include Thor::Actions
9
8
 
10
- map %w(--version -v) => :__print_version
11
-
12
- desc '--version, -v', 'print the version'
13
- def __print_version
14
- puts Doggy::VERSION
15
- end
16
-
17
9
  desc "pull [IDs]", "Pulls objects from Datadog"
18
10
 
19
11
  def pull(*ids)
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module Doggy
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module Doggy
@@ -23,8 +22,6 @@ module Doggy
23
22
  new_resource.description = resource.description
24
23
  elsif new_resource.is_a?(Doggy::Models::Monitor)
25
24
  new_resource.name = resource.name
26
- elsif new_resource.is_a?(Doggy::Models::Screen)
27
- new_resource.board_title = resource.board_title
28
25
  end
29
26
  new_resource.path = resource.path
30
27
  new_resource.save_local
@@ -39,20 +36,18 @@ module Doggy
39
36
  end
40
37
 
41
38
  def fork(resource)
42
- salt = Doggy.random_word
43
- forked_resource = resource.dup
44
- forked_resource.id = nil
39
+ forked_resource = resource.class.new(resource.attributes.except("id")) # TODO: Except "url" too
40
+ forked_resource.path = resource.path # TODO: should not be forked
45
41
  forked_resource.refute_read_only!
42
+
46
43
  if /dashboard/.match?(resource.class.to_s.downcase)
47
- forked_resource.title = "[#{salt}] " + forked_resource.title
48
- forked_resource.description = "[fork of #{resource.id}] " + forked_resource.title
49
- elsif /screen/.match?(resource.class.to_s.downcase)
50
- forked_resource.board_title = "[#{salt}] " + forked_resource.board_title
44
+ forked_resource.title = "[#{Doggy.random_word}] #{resource.title}"
51
45
  elsif /monitor/.match?(resource.class.to_s.downcase)
52
- forked_resource.name = "[#{salt}] " + forked_resource.name
46
+ forked_resource.name = "[#{Doggy.random_word}] #{resource.name}"
53
47
  else
54
48
  raise StandardError, 'Unknown resource type, cannot edit.'
55
49
  end
50
+
56
51
  forked_resource.save
57
52
  forked_resource
58
53
  end
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  require 'doggy/duration'
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  require 'parallel'
@@ -12,9 +11,20 @@ module Doggy
12
11
 
13
12
  def run
14
13
  @local_resources = Doggy::Model.all_local_resources
14
+ id_migration_mapping = {}
15
+
15
16
  if @ids.empty?
16
17
  Parallel.each(@local_resources) do |local_resource|
17
- if remote_resource = local_resource.class.find(local_resource.id)
18
+ remote_resource = local_resource.class.find(local_resource.id)
19
+ if (new_id = remote_resource&.attributes&.dig("dash", "new_id")) || (new_id = remote_resource&.attributes&.dig("new_id"))
20
+ id_migration_mapping[local_resource.id.to_s] = local_resource.class.find(new_id)
21
+ end
22
+
23
+ if remote_resource
24
+ if id_migration_mapping.key?(local_resource.id)
25
+ remote_resource.attributes = id_migration_mapping[local_resource.id].attributes
26
+ end
27
+
18
28
  remote_resource.path = local_resource.path
19
29
  remote_resource.save_local
20
30
  else
@@ -22,29 +32,34 @@ module Doggy
22
32
  end
23
33
  end
24
34
  else
25
- @ids.each { |id| pull_by_id(id.to_i) }
35
+ @ids.each { |id| pull_by_id(id.to_s) }
26
36
  end
27
37
  end
28
38
 
29
39
  private
30
40
 
31
41
  def pull_by_id(id)
32
- local_resources = @local_resources.find_all { |l| l.id == id }
42
+ local_resources = @local_resources.find_all { |l| l.id.to_s == id.to_s }
43
+ id_migration_mapping = {}
33
44
 
34
- remote_resources = [Models::Dashboard, Models::Monitor, Models::Screen].map do |klass|
35
- klass.find(id)
45
+ remote_resources = [Models::Dashboard, Models::Monitor].map do |klass|
46
+ result = klass.find(id.to_s)
47
+ if (new_id = result&.attributes&.dig("dash", "new_id")) || (new_id = result&.attributes&.dig("new_id"))
48
+ id_migration_mapping[id.to_s] = klass.find(new_id)
49
+ end
50
+ result
36
51
  end.compact
37
52
 
38
53
  if local_resources.size != remote_resources.size
39
- normalized_remote_resources = remote_resources.map { |remote_resource| [remote_resource.class.name, remote_resource.id] }
40
- normalized_local_resources = local_resources.map { |local_resource| [local_resource.class.name, local_resource.id] }
54
+ normalized_remote_resources = remote_resources.map { |remote_resource| [remote_resource.class.name, remote_resource.id.to_s] }
55
+ normalized_local_resources = local_resources.map { |local_resource| [local_resource.class.name, local_resource.id.to_s] }
41
56
  normalized_resource_diff = Hash[normalized_remote_resources - normalized_local_resources]
42
57
 
43
58
  # Here we traverse `remote_resources` to find remote resource with matching class name and id.
44
59
  # We cannot subtract `local_resources` from `remote_resources` because those are different kind of objects.
45
60
  remote_resources_to_be_saved = normalized_resource_diff.map do |klass, normalized_resource_id|
46
61
  remote_resources.find do |rr|
47
- rr.class.name == klass && rr.id == normalized_resource_id
62
+ rr.class.name == klass && rr.id.to_s == normalized_resource_id.to_s
48
63
  end
49
64
  end
50
65
 
@@ -52,6 +67,11 @@ module Doggy
52
67
  else
53
68
  local_resources.each do |local_resource|
54
69
  remote_resource = local_resource.class.find(local_resource.id)
70
+
71
+ if id_migration_mapping.key?(local_resource.id)
72
+ remote_resource.attributes = id_migration_mapping[local_resource.id].attributes
73
+ end
74
+
55
75
  remote_resource.path = local_resource.path
56
76
  remote_resource.save_local
57
77
  end
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module Doggy
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module Doggy
@@ -23,7 +23,7 @@ module Duration
23
23
  }
24
24
 
25
25
  def self.parse(value)
26
- unless match = DURATION_FORMAT.match(value)
26
+ unless (match = DURATION_FORMAT.match(value))
27
27
  raise ArgumentError, "not a duration: #{value.inspect}, "\
28
28
  "use digits followed by a unit (#{DURATION_UNITS.map { |k, v| "#{k} for #{v}" }.join(', ')})"
29
29
  end
@@ -0,0 +1,13 @@
1
+ class Hash
2
+ def sort_by_key(&block)
3
+ self.keys.sort(&block).reduce({}) do |seed, key|
4
+ seed[key] = self[key]
5
+ if seed[key].is_a?(Hash)
6
+ seed[key] = seed[key].sort_by_key(&block)
7
+ elsif seed[key].is_a?(Array)
8
+ seed[key] = seed[key].map { |i| i.sort_by_key(&block) }
9
+ end
10
+ seed
11
+ end
12
+ end
13
+ end
data/lib/doggy/model.rb CHANGED
@@ -1,30 +1,32 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  require "json"
5
4
  require "parallel"
6
5
  require "uri"
7
- require "virtus"
6
+ require "active_support/core_ext/hash/keys"
8
7
 
9
8
  module Doggy
10
9
  class Model
11
- include Virtus.model
10
+ # Denormalized object attributes.
11
+ attr_accessor :attributes
12
12
 
13
13
  # This stores the path on disk. We don't define it as a model attribute so
14
14
  # it doesn't get serialized.
15
15
  attr_accessor :path
16
16
 
17
- # indicates whether an object locally deleted
17
+ # Indicates whether an object locally deleted
18
18
  attr_accessor :is_deleted
19
19
 
20
20
  # This stores whether the resource has been loaded locally or remotely.
21
21
  attr_accessor :loading_source
22
22
 
23
23
  class << self
24
- attr_accessor :root
25
-
26
24
  def find(id)
27
- attributes = request(:get, resource_url(id), nil, [404])
25
+ attributes = request(:get, resource_url(id), nil, [404, 400])
26
+ if self == Doggy::Models::Dashboard
27
+ attributes = request(:get, resource_url(id, "dash"), nil, [404, 400]) if attributes['errors']
28
+ attributes = request(:get, resource_url(id, "screen"), nil, [404, 400]) if attributes['errors']
29
+ end
28
30
  return if attributes['errors']
29
31
  resource = new(attributes)
30
32
 
@@ -34,11 +36,13 @@ module Doggy
34
36
 
35
37
  def find_local(param)
36
38
  resources = Doggy::Model.all_local_resources
37
- if (id = param).is_a?(Integer) || (param =~ /^[0-9]+$/ && id = Integer(param))
38
- return resources.find { |res| res.id == id }
39
+ param = param.to_s
40
+ if (param =~ /^[0-9]+$/) || (param =~ /^[a-z0-9]+-[a-z0-9]+-[a-z0-9]+$/)
41
+ id = param
42
+ return resources.find { |res| res.id == id.to_s || res.id == id.to_i }
39
43
  end
40
- if id = param[%r{(dash/|screen/|monitors#)(\d+)}i, 2]
41
- return resources.find { |res| res.id == Integer(id) }
44
+ if (id = param[%r{(dashboard/|monitors#)(\d+)}i, 2])
45
+ return resources.find { |res| res.id == id.to_s || res.id == id.to_i }
42
46
  end
43
47
  full_path = File.expand_path(param.gsub('objects/', ''), Doggy.object_root)
44
48
  resources.find { |res| res.path == full_path }
@@ -84,10 +88,7 @@ module Doggy
84
88
  end
85
89
 
86
90
  def infer_type(attributes)
87
- has_key = ->(key) { attributes.key?(key.to_s) || attributes.key?(key.to_sym) }
88
- return Models::Dashboard if has_key.call('graphs')
89
- return Models::Monitor if has_key.call('message')
90
- return Models::Screen if has_key.call('board_title')
91
+ attributes.key?("message") ? Models::Monitor : Models::Dashboard
91
92
  end
92
93
 
93
94
  def request(method, url, body = nil, accepted_errors = nil)
@@ -103,11 +104,11 @@ module Doggy
103
104
  http.use_ssl = (uri.scheme == 'https')
104
105
 
105
106
  request = case method
106
- when :get then Net::HTTP::Get.new(uri.request_uri)
107
- when :post then Net::HTTP::Post.new(uri.request_uri)
108
- when :put then Net::HTTP::Put.new(uri.request_uri)
109
- when :delete then Net::HTTP::Delete.new(uri.request_uri)
110
- end
107
+ when :get then Net::HTTP::Get.new(uri.request_uri)
108
+ when :post then Net::HTTP::Post.new(uri.request_uri)
109
+ when :put then Net::HTTP::Put.new(uri.request_uri)
110
+ when :delete then Net::HTTP::Delete.new(uri.request_uri)
111
+ end
111
112
 
112
113
  request.content_type = 'application/json'
113
114
  request.body = body if body
@@ -149,15 +150,8 @@ module Doggy
149
150
  }.to_json)
150
151
  end
151
152
 
152
- def sort_by_key(hash, &block)
153
- hash.keys.sort(&block).each_with_object({}) do |key, seed|
154
- seed[key] = hash[key]
155
- if seed[key].is_a?(Hash)
156
- seed[key] = Doggy::Model.sort_by_key(seed[key], &block)
157
- elsif seed[key].is_a?(Array)
158
- seed[key].each_with_index { |e, i| seed[key][i] = sort_by_key(e, &block) if e.is_a?(Hash) }
159
- end
160
- end
153
+ def sort_by_key(hash)
154
+ hash
161
155
  end
162
156
 
163
157
  protected
@@ -167,18 +161,15 @@ module Doggy
167
161
  end
168
162
  end # class << self
169
163
 
170
- def ==(another_model)
171
- to_h == another_model.to_h
164
+ def ==(other)
165
+ to_h == other.to_h
172
166
  end
173
167
 
174
- def initialize(attributes = nil)
175
- root_key = self.class.root
176
-
177
- return super unless attributes && root_key
178
- return super unless attributes[root_key].is_a?(Hash)
168
+ def initialize(attributes = {})
169
+ @attributes = attributes.deep_stringify_keys
179
170
 
180
- attributes = attributes[root_key]
181
- super(attributes)
171
+ @attributes["id"] = @attributes["id"].to_s if @attributes["id"]
172
+ @attributes["options"] ||= {} if self.class == Doggy::Models::Monitor
182
173
  end
183
174
 
184
175
  def save_local
@@ -188,7 +179,7 @@ module Doggy
188
179
  end
189
180
 
190
181
  def to_h
191
- Doggy::Model.sort_by_key(super)
182
+ Doggy::Model.sort_by_key(attributes)
192
183
  end
193
184
 
194
185
  def validate
@@ -212,7 +203,7 @@ module Doggy
212
203
  end
213
204
 
214
205
  def destroy
215
- self.class.request(:delete, resource_url(id), nil, [404])
206
+ self.class.request(:delete, resource_url(id), nil, [404, 400])
216
207
  end
217
208
 
218
209
  def destroy_local
@@ -1,21 +1,50 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module Doggy
5
4
  module Models
6
5
  class Dashboard < Doggy::Model
7
- self.root = 'dash'
6
+ def id
7
+ attributes["id"]
8
+ end
9
+
10
+ def id=(v)
11
+ attributes["id"] = v
12
+ end
8
13
 
9
- attribute :id, Integer
10
- attribute :title, String
11
- attribute :description, String
14
+ def title
15
+ attributes["title"]
16
+ end
12
17
 
13
- attribute :graphs, Array[Hash]
14
- attribute :template_variables, Array[Hash]
15
- attribute :read_only, Boolean
18
+ def title=(v)
19
+ attributes["title"] = v
20
+ end
21
+
22
+ def description
23
+ attributes["description"]
24
+ end
25
+
26
+ def description=(v)
27
+ attributes["description"] = v
28
+ end
29
+
30
+ def read_only
31
+ if attributes["widgets"]
32
+ attributes["is_read_only"]
33
+ else
34
+ attributes["read_only"]
35
+ end
36
+ end
37
+
38
+ def read_only=(v)
39
+ if attributes["widgets"]
40
+ attributes["is_read_only"] = v
41
+ else
42
+ attributes["read_only"] = v
43
+ end
44
+ end
16
45
 
17
46
  def prefix
18
- 'dash'
47
+ 'dashboard'
19
48
  end
20
49
 
21
50
  def ensure_read_only!
@@ -26,22 +55,22 @@ module Doggy
26
55
  self.read_only = false
27
56
  end
28
57
 
29
- def self.resource_url(id = nil)
30
- ["https://app.datadoghq.com/api/v1/dash", id].compact.join("/")
58
+ def self.resource_url(id = nil, kind = "dashboard")
59
+ ["https://app.datadoghq.com/api/v1/#{kind}", id].compact.join("/")
31
60
  end
32
61
 
33
62
  def managed?
34
- !(title =~ Doggy::DOG_SKIP_REGEX)
63
+ title !~ Doggy::DOG_SKIP_REGEX
35
64
  end
36
65
 
37
66
  def ensure_managed_emoji!
38
67
  return unless managed?
39
- return if title =~ /\xF0\x9F\x90\xB6/
40
- self.title += " \xF0\x9F\x90\xB6"
68
+ return if title =~ /🐶/
69
+ self.title = "#{title} 🐶"
41
70
  end
42
71
 
43
72
  def human_url
44
- "https://#{Doggy.base_human_url}/dash/#{id}"
73
+ "https://#{Doggy.base_human_url}/dashboard/#{id}"
45
74
  end
46
75
 
47
76
  # Dashboards don't have a direct edit URL
@@ -1,70 +1,64 @@
1
- # encoding: utf-8
2
1
  # frozen_string_literal: true
3
2
 
4
3
  module Doggy
5
4
  module Models
6
5
  class Monitor < Doggy::Model
7
- class Options
8
- include Virtus.model
9
-
10
- attribute :escalation_message, String
11
- attribute :evaluation_delay, Integer
12
- attribute :include_tags, Boolean
13
- attribute :locked, Boolean
14
- attribute :new_host_delay, Integer
15
- attribute :no_data_timeframe, Integer
16
- attribute :notify_audit, Boolean
17
- attribute :notify_no_data, Boolean
18
- attribute :renotify_interval, Integer
19
- attribute :require_full_window, Boolean
20
- attribute :silenced, Hash
21
- attribute :thresholds, Hash
22
- attribute :timeout_h, Integer
23
- end
24
-
25
- attribute :id, Integer
26
- attribute :org_id, Integer
27
- attribute :name, String
28
-
29
- attribute :message, String
30
- attribute :query, String
31
- attribute :options, Options
32
- attribute :tags, Array[String]
33
- attribute :type, String
34
- attribute :multi, Boolean
6
+ def id
7
+ attributes["id"]
8
+ end
9
+
10
+ def id=(v)
11
+ attributes["id"] = v
12
+ end
13
+
14
+ def name
15
+ attributes["name"]
16
+ end
17
+
18
+ def name=(v)
19
+ attributes["name"] = v
20
+ end
21
+
22
+ def locked
23
+ attributes["options"]["locked"]
24
+ end
25
+
26
+ def locked=(v)
27
+ attributes["options"]["locked"] = v
28
+ end
29
+
30
+ def silenced
31
+ attributes["options"]["silenced"]
32
+ end
33
+
34
+ def silenced=(v)
35
+ attributes["options"]["silenced"] = v
36
+ end
35
37
 
36
38
  def prefix
37
39
  'monitor'
38
40
  end
39
41
 
40
42
  def ensure_read_only!
41
- if options
42
- options.locked = true
43
- else
44
- self.options = Options.new(locked: true)
45
- end
43
+ attributes["options"]["locked"] = true
46
44
  end
47
45
 
48
46
  def refute_read_only!
49
- if options
50
- options.locked = false
51
- else
52
- self.options = Options.new(locked: false)
53
- end
47
+ attributes["options"]["locked"] = false
54
48
  end
55
49
 
56
- def self.resource_url(id = nil)
57
- ["https://app.datadoghq.com/api/v1/monitor", id].compact.join("/")
50
+ def self.resource_url(id = nil, kind = "monitor")
51
+ ["https://app.datadoghq.com/api/v1/#{kind}", id].compact.join("/")
58
52
  end
59
53
 
60
54
  def managed?
61
- !(name =~ Doggy::DOG_SKIP_REGEX)
55
+ name !~ Doggy::DOG_SKIP_REGEX
62
56
  end
63
57
 
64
58
  def ensure_managed_emoji!
65
59
  return unless managed?
66
- return if name =~ /\xF0\x9F\x90\xB6/
67
- self.name += " \xF0\x9F\x90\xB6"
60
+ return if name =~ /🐶/
61
+ self.name += " 🐶"
68
62
  end
69
63
 
70
64
  def validate
@@ -74,11 +68,11 @@ module Doggy
74
68
  def toggle_mute!(action, body = nil)
75
69
  return unless %w[mute unmute].include?(action) && id
76
70
  attributes = request(:post, "#{resource_url(id)}/#{action}", body)
77
- if message = attributes['errors']
71
+ if (message = attributes['errors'])
78
72
  Doggy.ui.error(message)
79
73
  else
80
74
  self.attributes = attributes
81
- if local_version = Doggy::Model.find_local(id)
75
+ if (local_version = Doggy::Model.find_local(id))
82
76
  self.path = local_version.path
83
77
  end
84
78
  save_local
@@ -93,19 +87,15 @@ module Doggy
93
87
  "https://#{Doggy.base_human_url}/monitors##{id}/edit"
94
88
  end
95
89
 
96
- def to_h
97
- Doggy::Model.sort_by_key(super.merge(options: options.to_h))
98
- end
99
-
100
90
  private
101
91
 
102
92
  def ensure_renotify_interval_valid
103
- return unless options&.renotify_interval && options.renotify_interval.to_i > 0
93
+ return unless attributes.dig("options", "renotify_interval") && attributes.dig("options", "renotify_interval").to_i > 0
104
94
 
105
95
  allowed_renotify_intervals = [10, 20, 30, 40, 50, 60, 90, 120, 180, 240, 300, 360, 720, 1440] # minutes
106
- best_matching_interval = allowed_renotify_intervals.min_by { |x| (x.to_f - options.renotify_interval).abs }
107
- puts "WARN: Monitor #{id} uses invalid escalation interval (renotify_interval) #{options.renotify_interval}, using #{best_matching_interval} instead"
108
- options.renotify_interval = best_matching_interval
96
+ best_matching_interval = allowed_renotify_intervals.min_by { |x| (x.to_f - attributes["options"]["renotify_interval"]).abs }
97
+ puts "WARN: Monitor #{id} uses invalid escalation interval (renotify_interval) #{attributes["options"]["renotify_interval"]}, using #{best_matching_interval} instead"
98
+ attributes["options"]["renotify_interval"] = best_matching_interval
109
99
  end
110
100
  end # Monitor
111
101
  end # Models
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: doggy
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.1
4
+ version: 3.0.0.pre.beta1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vlad Gorodetsky
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2019-04-16 00:00:00.000000000 Z
12
+ date: 2019-05-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: parallel
@@ -39,20 +39,6 @@ dependencies:
39
39
  - - ">="
40
40
  - !ruby/object:Gem::Version
41
41
  version: '0'
42
- - !ruby/object:Gem::Dependency
43
- name: virtus
44
- requirement: !ruby/object:Gem::Requirement
45
- requirements:
46
- - - ">="
47
- - !ruby/object:Gem::Version
48
- version: '0'
49
- type: :runtime
50
- prerelease: false
51
- version_requirements: !ruby/object:Gem::Requirement
52
- requirements:
53
- - - ">="
54
- - !ruby/object:Gem::Version
55
- version: '0'
56
42
  - !ruby/object:Gem::Dependency
57
43
  name: rugged
58
44
  requirement: !ruby/object:Gem::Requirement
@@ -184,11 +170,10 @@ files:
184
170
  - lib/doggy/cli/push.rb
185
171
  - lib/doggy/cli/unmute.rb
186
172
  - lib/doggy/duration.rb
173
+ - lib/doggy/hash_sort.rb
187
174
  - lib/doggy/model.rb
188
175
  - lib/doggy/models/dashboard.rb
189
176
  - lib/doggy/models/monitor.rb
190
- - lib/doggy/models/screen.rb
191
- - lib/doggy/version.rb
192
177
  homepage: http://github.com/shopify/doggy
193
178
  licenses:
194
179
  - MIT
@@ -204,9 +189,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
204
189
  version: '2.5'
205
190
  required_rubygems_version: !ruby/object:Gem::Requirement
206
191
  requirements:
207
- - - ">="
192
+ - - ">"
208
193
  - !ruby/object:Gem::Version
209
- version: '0'
194
+ version: 1.3.1
210
195
  requirements: []
211
196
  rubyforge_project:
212
197
  rubygems_version: 2.7.6
@@ -1,52 +0,0 @@
1
- # encoding: utf-8
2
- # frozen_string_literal: true
3
-
4
- module Doggy
5
- module Models
6
- class Screen < Doggy::Model
7
- attribute :id, Integer
8
- attribute :board_title, String
9
-
10
- attribute :board_bgtype, String
11
- attribute :templated, Boolean
12
- attribute :template_variables, Array[Hash]
13
- attribute :widgets, Array[Hash]
14
- attribute :height, String
15
- attribute :width, String
16
- attribute :read_only, Boolean
17
-
18
- def prefix
19
- 'screen'
20
- end
21
-
22
- def ensure_read_only!
23
- self.read_only = true
24
- end
25
-
26
- def refute_read_only!
27
- self.read_only = false
28
- end
29
-
30
- def self.resource_url(id = nil)
31
- ["https://app.datadoghq.com/api/v1/screen", id].compact.join("/")
32
- end
33
-
34
- def managed?
35
- !(board_title =~ Doggy::DOG_SKIP_REGEX)
36
- end
37
-
38
- def ensure_managed_emoji!
39
- return unless managed?
40
- return if board_title =~ /\xF0\x9F\x90\xB6/
41
- self.board_title += " \xF0\x9F\x90\xB6"
42
- end
43
-
44
- def human_url
45
- "https://#{Doggy.base_human_url}/screen/#{id}"
46
- end
47
-
48
- # Screens don't have a direct edit URL
49
- alias_method :human_edit_url, :human_url
50
- end # Screen
51
- end # Models
52
- end # Doggy
data/lib/doggy/version.rb DELETED
@@ -1,6 +0,0 @@
1
- # encoding: utf-8
2
- # frozen_string_literal: true
3
-
4
- module Doggy
5
- VERSION = '2.1.1'
6
- end